聚合数据框中的行

时间:2014-11-15 00:45:48

标签: r dataframe aggregate

我有data.frame这种格式:

df <- data.frame(time = seq(0.2,4,0.2), behavior = c(rep(0,4),rep(1,4),rep(2,4),rep(0,4),rep(1,4)), n1 = rnorm(20), n2 = rnorm(20))

因此df中的每一行都是一个时间点(实际时间由df$time表示),df$behavior表示在该时间点进行的实验中观察到的行为。< / p>

我想根据相同的连续data.frame值(即相同的观察行为)聚合df$behaviordf$time应该相加,生成的df$n1df$n2,...列应该在df$time的总和上取平均值。

因此,对于此示例,结果将是:

> agg.df
  time behavior          n1          n2
1  2.0        0 -1.19640776 -1.78875416
2  5.2        1 -0.52219794  0.15352409
3  8.4        2  0.40486487 -0.12017916
4 11.6        0  0.15282416 -0.08090696
5 14.8        1  0.05377323 -0.01250031

实现这一目标的最有效方法是什么?

1 个答案:

答案 0 :(得分:2)

以下是使用dplyr的一种方法。由于您在df中使用的rnorm没有set.seed,因此我的结果与您的结果不同。

df %>%
    group_by(group = cumsum(c(T, diff(behavior) != 0))) %>% # assigning groups
    summarise(Time = sum(time),
              ave.n1 = sum(n1) / Time,
              ave.n2 = sum(n2) / Time)


# group Time      ave.n1      ave.n2
#1    1  2.0  0.68164245 -1.57266432
#2    2  5.2 -0.26419520  0.19598772
#3    3  8.4 -0.04105184  0.24406783
#4    4 11.6  0.10536325 -0.28962844
#5    5 14.8 -0.09449933 -0.02142792

如果你有n1-n200,你可以这样做。请注意,你的n1-n200是 在这里覆盖。你可以做mutate_each(funs(./time), vars = matches("^n"))。这将 使用列名称创建200列,如var1,var2。您需要自己替换名称。 使用当前版本的dplyr,这个重命名部分有点痛苦。但你可以轻松做到 例如,使用gsub

df %>%
    group_by(group = cumsum(c(T, diff(behavior) != 0))) %>%
    summarise_each(funs(sum = sum(., na.rm = TRUE))) %>%
    mutate_each(funs(./time), matches("^n")) %>%
    select(-behavior)

如果你想保持原来的行为,你可以这样做。

df %>%
    group_by(group = cumsum(c(T, diff(behavior) != 0))) %>%
    summarise(behavior = behavior[1]) -> foo;
    df %>%
    group_by(group = cumsum(c(T, diff(behavior) != 0))) %>%
    summarise(Time = sum(time),
              ave.n1 = sum(n1) / Time,
              ave.n2 = sum(n2) / Time) %>%
    do(cbind(.,foo[,2]))

# group Time      ave.n1      ave.n2 behavior
#1    1  2.0  0.93849292  0.90373785        0
#2    2  5.2  0.26211881 -0.11678684        1
#3    3  8.4  0.12171471  0.15838066        2
#4    4 11.6  0.11046081  0.17450358        0
#5    5 14.8 -0.06480093  0.03401513        1