1

我经常尝试在两个不同的场景/测试/期间测量百分比变化。

一个示例数据集:

library(dplyr)
set.seed(11)
toy_dat <- data.frame(state = sample(state.name,3, replace=F), 
                 experiment=c('control','measure'), 
                 accuracy=sample(30:50, size=6, replace=T), 
                 speed=sample(21:39, size=6, replace=T)) %>% arrange(state)


     state experiment accuracy speed
1  Alabama    measure       31    24
2  Alabama    control       36    37
3  Indiana    control       30    23
4  Indiana    measure       31    38
5 Missouri    control       50    29
6 Missouri    measure       48    34

然后我求助于写一些像这样可怕的东西:

result <- toy_dat %>%  group_by(state) %>% arrange(experiment) %>%
  summarise(acc_delta = (accuracy[2]-accuracy[1])/accuracy[1],
            speed_delta = (speed[2]-speed[1])/speed[1])

但是,当可测量的数量开始增长时,上述解决方案根本无法扩展。此外,代码在排序方面非常脆弱。

我对 R 很陌生。我希望这是一种足够普遍的模式,以便有众所周知的(更智能的)解决方案来解决这个问题。

我将不胜感激任何帮助/指针。

4

1 回答 1

1

只需创建您自己的自定义函数并使用summarise_each,以便一次将其应用于所有测量值(无论您有多少测量值)

delta_fun <- function(x) diff(x)/x[1L]

toy_dat %>%  
  group_by(state) %>% 
  arrange(experiment) %>%
  summarise_each(funs(delta_fun), -experiment)

# Source: local data frame [3 x 3]
# 
#      state    accuracy      speed
# 1  Alabama -0.13888889 -0.3513514
# 2  Indiana  0.03333333  0.6521739
# 3 Missouri -0.04000000  0.1724138

正如您提到的,您是 R 新手,这是另一个很棒的包,您可以使用它来实现相同的效果

library(data.table)
setDT(toy_dat)[order(experiment), 
               lapply(.SD, delta_fun), 
               .SDcols = -"experiment",
               by = state]
#       state    accuracy      speed
# 1:  Alabama -0.13888889 -0.3513514
# 2:  Indiana  0.03333333  0.6521739
# 3: Missouri -0.04000000  0.1724138
于 2015-03-08T22:41:29.343 回答