【问题标题】:Calculate elapsed "times", where the reference time depends on a factor计算经过的“时间”,其中参考时间取决于一个因素
【发布时间】:2012-06-24 01:52:21
【问题描述】:

我正在尝试计算数据框中的经过时间,其中经过时间的“开始”值取决于数据框中因子列的值。 (为了简单的问题,我将时间值视为数字而不是时间对象 - 我的问题是关于拆分应用组合,而不是时间对象)。我的数据框如下所示:

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

这很不雅,而且看起来很脆弱。肯定有更好的方法吗?

【问题讨论】:

    标签: r plyr


    【解决方案1】:

    当结果是一个长度与数据帧中的行数相同的向量时,您首先应该考虑“ave”函数:

     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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

      • 不会用transform更自然一点:ddply(df,.(id),transform,elapsed = time - min(time))
      • 可能。不过这不是我马上想到的。我整天都在研究测度论,但我的脑子不太正常。
      • 呃。我的同情。喝杯啤酒,这会让你的大脑恢复正常工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 2020-12-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      相关资源
      最近更新 更多