计算因子水平之间变量的差异

时间:2015-11-22 13:55:25

标签: r dataframe

我有一个data.frame,在多个时间点为每个主题测量一个值。它简化了这个:

> set.seed(42)
> x = data.frame(subject=rep(c('a', 'b', 'c'), 3), time=rep(c(1,2,3), each=3), value=rnorm(3*3, 0, 1))
> x
  subject time       value
1       a    1  1.37095845
2       b    1 -0.56469817
3       c    1  0.36312841
4       a    2  0.63286260
5       b    2  0.40426832
6       c    2 -0.10612452
7       a    3  1.51152200
8       b    3 -0.09465904
9       c    3  2.01842371

我想计算每个时间点和每个主题的value变化。对于这个简单的例子,我目前的解决方案是:

> x$diff[x$time==1] = x$value[x$time==2] - x$value[x$time==1]
> x$diff[x$time==2] = x$value[x$time==3] - x$value[x$time==2]
> x
  subject time       value       diff
1       a    1  1.37095845 -0.7380958
2       b    1 -0.56469817  0.9689665
3       c    1  0.36312841 -0.4692529
4       a    2  0.63286260  0.8786594
5       b    2  0.40426832 -0.4989274
6       c    2 -0.10612452  2.1245482
7       a    3  1.51152200         NA
8       b    3 -0.09465904         NA
9       c    3  2.01842371         NA

...然后删除最后一行。但是,在我的实际数据集中,time的级别更高,我需要为多个列而不是value执行此操作。代码变得非常难看。有一个巧妙的方法来做到这一点?

3 个答案:

答案 0 :(得分:4)

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(x)),按'subject'分组,我们将下一个值(shift(value, type='lead'))的差值与当前值和assign({ {1}})输出以创建“Diff”列。

:=

答案 1 :(得分:3)

您可以尝试aveave将函数应用于值的子集,有关详细信息,请参阅?ave,例如:

x$diff <- ave(x$value, x$subject, FUN=function(x)c(diff(x), NA))
x
#   subject time       value       diff
# 1       a    1  1.37095845 -0.7380958
# 2       b    1 -0.56469817  0.9689665
# 3       c    1  0.36312841 -0.4692529
# 4       a    2  0.63286260  0.8786594
# 5       b    2  0.40426832 -0.4989274
# 6       c    2 -0.10612452  2.1245482
# 7       a    3  1.51152200         NA
# 8       b    3 -0.09465904         NA
# 9       c    3  2.01842371         NA

BTW diff函数要求订购time

编辑:使用set.seed(42)更新。

答案 2 :(得分:3)

您可以使用dplyr

library(dplyr)
x %>% 
  arrange(time, subject) %>% 
  group_by(subject) %>% 
  mutate(diff = c(diff(value), NA))
# Source: local data frame [9 x 4]
# Groups: subject [3]
# 
#   subject  time       value        diff
#    (fctr) (dbl)       (dbl)       (dbl)
# 1       a     1  1.30970525 -1.66596287
# 2       b     1  0.12556761 -0.06070412
# 3       c     1 -1.09423634  1.38590546
# 4       a     2 -0.35625763  0.91417329
# 5       b     2  0.06486349  0.06652424
# 6       c     2  0.29166912 -0.98495562
# 7       a     3  0.55791566          NA
# 8       b     3  0.13138773          NA
# 9       c     3 -0.69328649          NA

如果您想摆脱NA,请添加%>% na.omit