2015-03-31 12 views
3

这里有一个data.table如何申请一个函数,其中每个调用返回data.table

dt <- data.table(group = c("a","a","a","b","b","b"), x = c(1,3,5,1,3,5), y= c(3,5,8,2,8,9)) 
dt 
    group x y 
1:  a 1 3 
2:  a 3 5 
3:  a 5 8 
4:  b 1 2 
5:  b 3 8 
6:  b 5 9 

及这里的一个data.table和回报进行动作的功能排个data.table的子集一个data.table

myfunc <- function(dt){ 
    # Hyman spline interpolation (which preserves monotonicity) 

    newdt <- data.table(x = seq(min(dt$x), max(dt$x))) 
    newdt$y <- spline(x = dt$x, y = dt$y, xout = newdt$x, method = "hyman")$y 
    return(newdt) 
} 

我该如何申请myfunc于DT每个子集的“组”列定义?换句话说,我希望有一个高效,广义的方式来做到这一点

result <- rbind(myfunc(dt[group=="a"]), myfunc(dt[group=="b"])) 
result 
    x  y 
1: 1 3.000 
2: 2 3.875 
3: 3 5.000 
4: 4 6.375 
5: 5 8.000 
6: 1 2.000 
7: 2 5.688 
8: 3 8.000 
9: 4 8.875 
10: 5 9.000 

编辑:我已经更新了我的样本数据集,并myfunc,因为我认为这是最初过于简单,并邀请变通的实际问题,我正在努力解决。

+0

您函数创建不必要的拷贝,只要做'dt [,。(x = seq(min(x),max(x)+ 1),y = rep(y,each = 2)),或者= group]' – 2015-03-31 21:09:03

+0

或者,定义你的函数如下面的myfunc < - function(x,y){ list(x = seq(min(x),max(x)+1),y = rep(y,each = 2))}'然后执行dt [,myfunc(x,y),by = group ]' – 2015-03-31 21:12:03

+0

@DavidArenburg看到我的编辑(对不起) – Ben 2015-03-31 21:18:08

回答

6

data.table的整个想法既有记忆效率又很快。因此,我们从来没有data.table范围(仅在极少数情况下)中使用$,我们没有在data.table小号环境(目前,甚至.SD有一个开销)创建data.table对象。

在你的情况,你可以利用data.tablenon-standard evaluation功能和定义功能如下

myfunc <- function(x, y){ 
    temp = seq(min(x), max(x)) 
    y = spline(x = x, y = y, xout = temp, method = "hyman")$y 
    list(x = temp, y = y) 
} 

然后dt范围内的实施是直截了当

dt[, myfunc(x, y), by = group] 
#  group x  y 
# 1:  a 1 3.0000 
# 2:  a 2 3.8750 
# 3:  a 3 5.0000 
# 4:  a 4 6.3750 
# 5:  a 5 8.0000 
# 6:  b 1 2.0000 
# 7:  b 2 5.6875 
# 8:  b 3 8.0000 
# 9:  b 4 8.8750 
# 10:  b 5 9.0000 
+0

NSE是“非标评估”,呃?所以建议谷歌,无论如何。 – Frank 2015-03-31 22:25:30

+0

@Frank,是的.... – 2015-03-31 22:28:22

相关问题