r 如何将mapply与数据表一起使用

Jer*_*ryN 5 r mapply data.table

我想要在数据表中执行看似简单的 mapply 应用程序。我想将一系列数据表列乘以另一列中的值。这是我的功能。y 是与其他列中的值相乘的单列。xIn 是要执行此操作的列名称。

f.xRatio <- function(xIn, y) {return(y * (xIn + 1)/(xIn - 1))}
Run Code Online (Sandbox Code Playgroud)

我有一个数据表,其中有一个名为 GDPratio 的列和一些名称为 x.food1、x.food2 等的列。我将这些列名称放入名为 x 的变量中

x <- paste0("x.", foodNames)
Run Code Online (Sandbox Code Playgroud)

我使用该函数创建的新列的名称创建另一个变量

xRatio <- paste0("xRatio.", foodNames)
Run Code Online (Sandbox Code Playgroud)

以下是我尝试使用 mapply 从函数创建 xRatio 列的两个版本。

dt[, (xRatio) := mapply(FUN = f.xRatio, xIn = .SD, y = GDPRatio), .SDcols = (x)]

dt[, (xRatio) := mapply(FUN = f.xRatio, xIn = .(x), y = GDPRatio)]
Run Code Online (Sandbox Code Playgroud)

两者都不起作用。我认为第一个已经很接近了。我希望有人能够指出我逻辑中的缺陷,而无需我创建可重现的示例。

akr*_*run 5

如果我们使用Map/mapply,请确保将单列“GDPRatio”括在 a 中,以将其作为在 中的列list上回收的单个单元。 list.SD

dt[, (xRatio) := Map(f.xRatio, .SD, list(GDPRatio)), .SDcols = x]
Run Code Online (Sandbox Code Playgroud)

否则,该单元将是 a 中的单个元素vector,并且它会与 的相应列一起回收.SD,并导致lengthOP 代码中所述的问题

dt[, (xRatio) := Map(f.xRatio, .SD, GDPRatio), .SDcols = x]
Run Code Online (Sandbox Code Playgroud)

警告消息: 1:在 mapply(FUN = f, ..., SIMPLIFY = FALSE) 中:
较长的参数不是较短长度的倍数 2:In [.data.table(dt, , :=((xRatio), Map(f.xRatio, .SD) , GDPRatio)), : 提供 2 列以分配值列表(长度 5)(3 未使用)

数据

foodNames <- c("food1", "food2")
x <- paste0("x.", foodNames)
xRatio <- paste0("xRatio.", foodNames)

set.seed(24)
dt <- data.table(x.food1 = 2:6, x.food2 = 6:10, val = rnorm(5), 
                GDPRatio = c(0.5, 0.2, 0.3, 0.4, 0.1))
Run Code Online (Sandbox Code Playgroud)