我有一个数据框,需要计算每个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
答案 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))