计算经过的“时间”,其中参考时间取决于因子

时间:2012-06-24 01:52:21

标签: r plyr

我正在尝试计算数据框中的经过时间,其中经过时间的“开始”值取决于数据框中因子列的值。 (仅仅是问题,我会将时间值视为数字而不是时间对象 - 我的问题是关于split-apply-combine,而不是时间对象)。我的数据框如下所示:

df <- data.frame(id=gl(2, 3, 5, labels=c("a", "b")), time=1:5)

我想通过从每次减去每个因子水平的最小时间来计算经过的时间(尽管为了这个例子,我只处理数值,而不是时间值)。所以我想将数据框拆分id,从y列中的每个元素中减去最小y值,然后返回转换后的数据框(或数据框)值。我想最终得到类似的东西:

> dfTrans
id  time  elapsed
a      1        0
a      2        1
a      3        2
b      4        0
b      5        1   

对plyr来说似乎是一项完美的任务,但我找不到一个简单的解决方案。

我能想到的最好的是

elapsed <- dlply(df, .(id), function(x) x$time - min(x$time))
elapsed_comb <- NA
for(i in 1:length(names(elapsed))) {
  elapsed_comb <- c(elapsed_comb, elapsed[[i]])
}
elapsed_comb <- elapsed_comb[-1]
df$elapsed <- elapsed_comb

这是不优雅的,似乎很脆弱。当然有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

&#39; ave&#39;当结果是一个长度与数据帧中行数相同的向量时,你应该首先考虑函数:

 df$elapsed <- ave(df$time, df$id, FUN=function(x) x -min(x) )
 df
  id time elapsed
1  a    1       0
2  a    2       1
3  a    3       2
4  b    4       0
5  b    5       1

答案 1 :(得分:2)

这是一个ddply解决方案

ddply(df, .(id), summarize, time = time, elapsed = seq(length(id))-1)

和一个使用rle而不是

df$elapsed <- unlist(sapply(rle(as.numeric(df$id))$lengths, seq))-1