我有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$behavior
。 df$time
应该相加,生成的df$n1
,df$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
实现这一目标的最有效方法是什么?
答案 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