R data.table 根据 j 中的列动态过滤行

R data.table dynamically filter rows based on columns in j

我正在处理一个需要为少数预测变量生成 MAPE 的需求。为此,我使用 MAP 函数在 data.table 中生成带有 MAPE 值的摘要 table。因此结果输出应该有 4 行 x 6 列,每个城市 1 行和 1 个城市列后跟 a1、a2、a3、a4、a5,每个单元格中都有 MAPE 值。

下面是我使用的示例数据和代码(注意 - 被认为是 a1、a2、a3....实际和 p1、p2、p3...如预测)-

library(data.table)

set.seed(123)
id <- seq(1001,1100,1)
city <- sample(1:4,100,replace = T)
a1 <- sample(1:100,100,replace = T)
a2 <- sample(1:100,100,replace = T)
a3 <- sample(1:100,100,replace = T)
a4 <- sample(1:100,100,replace = T)
a5 <- sample(1:100,100,replace = T)
p1 <- sample(1:100,100,replace = T)
p2 <- sample(1:100,100,replace = T)
p3 <- sample(1:100,100,replace = T)
p4 <- sample(1:100,100,replace = T)
p5 <- sample(1:100,100,replace = T)

df1 <- as.data.table(data.frame(id,city,a1,a2,a3,a4,a5,p1,p2,p3,p4,p5))


sum1 <- df1[, Map(function(x,y) mean(as.numeric(abs(get(x)-get(y))/get(x))*100),
                                                                   paste("a",1:5, sep = ""),
                                                                   paste("p",1:5, sep = "")),by=city]

现在我想为 x==y 然后 x > yx < y 的行生成相同的摘要......我认为最简单的方法是在 i 中传递它,但是如何做到这一点我没有得到.....当我尝试将它作为 function(x,y) get(x)==get(y) 传递时它给出错误

i has not evaluated to logical, integer or double

请推荐

更新后的答案: 由于您希望每个 ==>< 有 3 个单独的数据表,我使用了lapply 使用您在 post 中 post 编写的相同代码逐一处理这些操作。

运算符(例如 ==)作为 z 传递给 Map。因为这是一个 'operator' 你不能使用 get(z) 所以为了解决这个问题我使用 do.call 应用 fn 函数(即 == 运算符)变量列表。

Map 函数中,我首先根据 fn 值(即 z)过滤数据,如 x1y1。然后对这些子集应用MAPE公式得到最终结果。

lapply(c("==", ">", "<"), 
       function(z) df1[, 
                       Map(function(x, y, fn = z){
                         x1 <- get(x)[do.call(fn, list(get(x), get(y)))]
                         y1 <- get(y)[do.call(fn, list(get(x), get(y)))]
                         mean(as.numeric(abs(x1 - y1) / x1) * 100)
                         },
                         paste0("a", 1:5),
                         paste0("p", 1:5),
                         z), 
                       by = city])