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

时间:2018-06-12 09:21:53

标签: r filter data.table lapply map-function

我正在制定一项要求,我需要为少数预测变量生成MAPE。为此,我使用MAP函数生成一个包含 data.table 中MAPE值的汇总表。因此,结果输出应该有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 .....的行生成相同的摘要,这是我能想到的最简单的方法它在但是如何做到这一点我没有得到.....当我尝试将它作为function(x,y) get(x)==get(y)传递时它会给出错误

  

我没有评估为逻辑,整数或双

请建议

1 个答案:

答案 0 :(得分:1)

更新后的答案:您希望为==>和{...}提供3个单独的数据表。 <,我已使用lapply使用您在帖子中发布的相同代码逐个处理这些操作。

运营商(例如==)作为Map传递给z。由于这是一个&#39;运营商&#39;您无法使用get(z)因此,为了解决此问题,我使用do.callfn函数(即==运算符)应用于变量列表。

Map函数中,我首先根据fn值(即z)将数据过滤为x1&amp; y1。然后将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])