使用dplyr

时间:2017-10-24 23:11:54

标签: r dplyr

我有一个结构如下:

   day  theta
1   1    2.1
2   1    2.1
3   2    3.2
4   2    3.2
5   5    9.5
6   5    9.5
7   5    9.5

请注意,tibble包含每个day的多行,而对于每个daytheta的相同值重复任意次数。 (tibble包含其他任意列,需要这种重复结构。)

我想使用dplyr对几天内theta的值进行累加求和,这样,在上面的示例中,2.1只添加了一次3.2将改变tibble以便附加新的累积和(c.theta),如下所示:

   day  theta  c.theta
1   1    2.1     2.1
2   1    2.1     2.1
3   2    3.2     5.3
4   2    3.2     5.3
5   5    9.5     14.8
6   5    9.5     14.8
7   5    9.5     14.8 
...

我对group_by day以及cumsumtheta的初步努力仅导致对整套数据的累积总结(例如2.1 + 2.1 + 3.2 ...)这是不可取的。在我的Stack Overflow搜索中,我可以在组内找到许多examples的累积求和,但从不在组之间找到,如上所述。向正确的方向推动将非常感激。

3 个答案:

答案 0 :(得分:3)

dplyr中执行此操作我想出了一个非常类似于PoGibas的解决方案 - 使用distinct每天只获取一行,找到总和并合并回来:

df = read.table(text="day  theta
1   1    2.1
2   1    2.1
3   2    3.2
4   2    3.2
5   5    9.5
6   5    9.5
7   5    9.5", header = TRUE)

cumsums = df %>%
    distinct(day, theta) %>%
    mutate(ctheta = cumsum(theta))

df %>%
    left_join(cumsums %>% select(day, ctheta), by = 'day')

答案 1 :(得分:2)

不是dplyr,而只是替代data.table解决方案:

library(data.table)
# Original table is called d
setDT(d)
merge(d, unique(d)[, .(c.theta = cumsum(theta), day)])

   day theta c.theta
1:   1   2.1     2.1
2:   1   2.1     2.1
3:   2   3.2     5.3
4:   2   3.2     5.3
5:   5   9.5    14.8
6:   5   9.5    14.8
7:   5   9.5    14.8

PS:如果您想保留其他列,则必须使用unique(d[, .(day, theta)])

答案 2 :(得分:1)

在基数R中,您可以使用split<-tapply来返回所需的结果。

# construct 0 vector to fill in
dat$temp <- 0
# fill in with cumulative sum for each day
split(dat$temp, dat$day) <- cumsum(tapply(dat$theta, dat$day, head, 1))

在这里,tapply返回每天送到cumsum的theta的第一个元素。累积金额的元素使用split<-每天输入。

返回

dat
  day theta temp
1   1   2.1  2.1
2   1   2.1  2.1
3   2   3.2  5.3
4   2   3.2  5.3
5   5   9.5 14.8
6   5   9.5 14.8
7   5   9.5 14.8