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

R data.table在所有行上应用具有多列输入的函数,并获得合理的输出

  •  2
  • interested_in_the_world  · 技术社区  · 10 年前

    我试图将一个函数应用于data.table的所有行,同时使用多个列作为输入,输出可以是一行或两行数据。我的data.table有800000行。

    这是我最近的一次尝试。这里的作用当然是正确性、效率和输出结构的易用性。

    library(data.table)
    d0 = as.Date("2014/01/01")
    sdays = seq(d0,d0+99,by=1)
    gg=data.table(id=1:100,event_date = sdays)  
    setkey(gg, id)
    
    test_func = function(id,day){
      delta = day - d0
      if(delta == 0 ){
        rcomb = c(id, 0, 100, 1,0)
      } else if(delta != 100 ){
        r1 = c(id, 0, delta, 0, 0)
        r2 = c(id, delta, 100,   1, 0)
        rcomb = rbind(r1,r2)
      }
      rcomb
    }
    
    att = gg[, test_func( get("id"), get("event_date")), by=id]
    att
    

    关于如何使用快速数据表技巧有什么想法吗?我已经做了几个小时了,但还没有接近:/至于输出,我希望它是一个列表,每个原始行有一个条目,这样我就可以调用 do.call rbind 谢谢

    因此,让我举一个理想输出的例子,但效率非常低:

    some_list = vector("list", 100)
    for(i in 1:100) {
      some_list[[i]] <- test_func(gg$id[i], gg$event_date[i])
    }
    happy=do.call(rbind,some_list)
    head(happy)
       [,1] [,2] [,3] [,4] [,5]
          1    0  100    1    0
    r1    2    0    1    0    0
    r2    2    1  100    1    0
    r1    3    0    2    0    0
    r2    3    2  100    1    0
    r1    4    0    3    0    0
    
    1 回复  |  直到 10 年前
        1
  •  2
  •   mnel    10 年前

    如果您想为data.table创建4列,类似以下内容将起作用

    test_func = function(day){
        delta = day - d0
        if(delta == 0 ){
            rcomb = list(0, 100, 1,0)
        } else if(delta != 100 ){
         rcomb <- list(c(0,delta), c(100,delta), c(0,1), c(0,0))
    
        }
        rcomb
    }
    
    att = gg[, test_func(event_date), by=id]
    att
    
    推荐文章