在数据框的每个子集中应用函数

时间:2016-09-05 03:17:08

标签: r

我有一个数据框,需要计算每个ID中连续条目之间的差异,但是希望这样做而不必为每个ID创建单独的数据帧,然后再加入(我当前的解决方案)。以下是使用与数据框类似的结构的示例。

df = as.data.frame(matrix(nrow = 20,ncol =2 ))
names(df) = c("ID","number")
df$ID = sample(c("A","B","C"),20,replace = T)
df$number = rnorm(20,mean = 5)

我可以使用此函数轻松计算连续行之间的差异

roll.dif <-function(x) {
 difference = rollapply(x,width = 2, diff, fill=NA, align = "right")
 return(difference)
}

df$dif = roll.dif(df$number)

但是我想在每个ID中执行此操作。我尝试使用基于此答案的Apply function conditionally作为

with(df, tapply(number, ID, FUN = roll.dif))

我也试过用

by(df$number,df$ID,FUN = roll.dif)

这两个都给了我正在寻找的答案,但我无法弄清楚如何让他们回到数据框中。我希望输出看起来像这样:

    ID  number       dif
 1  A   3.967251     NA
 2  B   3.771882     NA
 3  A   5.920705     1.953454
 4  A   7.517528     1.596823
 5  B   5.252357     3.771882
 6  B   4.811998    -0.440359
 7  B   3.388951    -1.423047
 8  A   5.284527    -2.233001
 9  C   6.070546     NA
 10 A   5.319934     0.035407
 11 A   5.517615     0.197681
 12 B   5.454738     2.065787
 13 C   6.402359     0.331813
 14 C   5.617123    -0.785236
 15 A   5.692807     0.175192
 16 C   4.902007    -0.715116
 17 B   4.975184    -0.479554
 18 A   6.05282      0.360013
 19 C   3.677114    -1.224893
 20 C   4.883414     1.2063

2 个答案:

答案 0 :(得分:2)

您可以像这样使用dplyr

df %>% group_by(ID) %>% mutate(dif=roll.dif(number))

答案 1 :(得分:1)

我们可以使用data.table

library(data.table)
setDT(df)[, dif := roll.dif(number), by = ID]

base R选项为ave

df$dif <- with(df, ave(number, ID, FUN = roll.dif))