代码之家  ›  专栏  ›  技术社区  ›  user1412

r data.table根据j中的列动态筛选行

  •  1
  • user1412  · 技术社区  · 7 年前

    我正在处理一个需求,在这个需求中,我需要为几个预测变量生成MAPE。为此,我使用map函数生成一个包含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 > y x < y ……我能想到的最简单的方法就是把它传进去。 但如何做到这一点……当我试图将其作为 function(x,y) get(x)==get(y) 它产生错误

    我没有计算为逻辑、整数或双精度

    请建议

    1 回复  |  直到 7 年前
        1
  •  1
  •   Prem    7 年前

    更新的答案: 因为您希望每个表有3个独立的数据表 == ,请 > &安培; < ,我用过 lapply 要使用您在日志中发布的相同代码逐个处理这些操作。

    操作员(例如 == )传递给 Map 作为 z .因为这是一个“接线员”,你不能用 get(z) 所以为了解决这个问题,我用了 do.call 应用 fn 功能(即 == operator)在变量列表上。

    地图 我首先筛选的数据基于的函数 财务 价值(即 Z轴 )作为 x1 &安培; 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])