Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ddply将函数应用于一组行 我用得相当多,但我不认为自己是专家。我有一个数据框(df),其中包含分组变量“Group”,其值为“a”、“B”和“C”,要汇总的变量“Var”具有数值。如果我使用 ddply(df, .(Group), summarize, mysum=sum(Var))_R_Grouping_Plyr - Fatal编程技术网

使用ddply将函数应用于一组行 我用得相当多,但我不认为自己是专家。我有一个数据框(df),其中包含分组变量“Group”,其值为“a”、“B”和“C”,要汇总的变量“Var”具有数值。如果我使用 ddply(df, .(Group), summarize, mysum=sum(Var))

使用ddply将函数应用于一组行 我用得相当多,但我不认为自己是专家。我有一个数据框(df),其中包含分组变量“Group”,其值为“a”、“B”和“C”,要汇总的变量“Var”具有数值。如果我使用 ddply(df, .(Group), summarize, mysum=sum(Var)),r,grouping,plyr,R,Grouping,Plyr,然后我得到A,B和C的和,这是正确的。但我想做的是,当分组变量在数据帧中排列时,对分组变量进行求和。例如,如果数据帧具有 Group Var A 1.3 A 1.2 A 0.4 B 0.3 B 1.3 C 1.5 C 1.7 C 1.9 A 2.1 A 2.4 B 6.7 期望的结果 A 2.9 B 1.6

然后我得到A,B和C的和,这是正确的。但我想做的是,当分组变量在数据帧中排列时,对分组变量进行求和。例如,如果数据帧具有

Group    Var
A        1.3
A        1.2
A        0.4
B        0.3
B        1.3
C        1.5
C        1.7
C        1.9
A        2.1
A        2.4
B        6.7
期望的结果

A        2.9
B        1.6
C        5.1
A        4.5
B        6.7
因此,所需的输出对每组组变量执行数学函数,而不是对单个组变量的所有实例执行数学函数。这可以在ddply中完成吗

资料


dat这里有一种方法可以使用最近在
data.table
v1.9.6中实现的
rleid()
函数来实现这一点。看

这将根据需要生成分组ID:

require(data.table) ## v1.9.6+
DT = as.data.table(dat)
rleid(DT$Group)
# [1] 1 1 1 2 2 3 3 3 4 4 5
我们可以直接使用它进行如下汇总:

DT[, .(sum=sum(Var)), by=.(Group, rleid(Group))]
#    Group rleid sum
# 1:     A     1 2.9
# 2:     B     2 1.6
# 3:     C     3 5.1
# 4:     A     4 4.5
# 5:     B     5 6.7

HTH

这里是基本等价物

dat <- structure(list(Group = c("A", "A", "A", "B", "B", "C", "C", "C", "A", "A", "B"),
                      Var = c(1.3, 1.2, 0.4, 0.3, 1.3, 1.5, 1.7, 1.9, 2.1, 2.4, 6.7)),
                 .Names = c("Group", "Var"), class = "data.frame", row.names = c(NA, -11L))

with(dat, cumsum(c(1L, Group[-length(Group)] != Group[-1])))
# [1] 1 1 1 2 2 3 3 3 4 4 5
或者,您可以实际使用
rle
,但它需要一个原子向量,因此如果您使用的是因子,则需要额外的步骤(即,
as.vector


rleid2我找到的解决方案是rle()函数。
dat <- structure(list(Group = c("A", "A", "A", "B", "B", "C", "C", "C", "A", "A", "B"),
                      Var = c(1.3, 1.2, 0.4, 0.3, 1.3, 1.5, 1.7, 1.9, 2.1, 2.4, 6.7)),
                 .Names = c("Group", "Var"), class = "data.frame", row.names = c(NA, -11L))

with(dat, cumsum(c(1L, Group[-length(Group)] != Group[-1])))
# [1] 1 1 1 2 2 3 3 3 4 4 5
rleid <- function(x) cumsum(c(1L, x[-length(x)] != x[-1]))

(dat <- within(dat, id <- rleid(Group)))
#    Group Var id
# 1      A 1.3  1
# 2      A 1.2  1
# 3      A 0.4  1
# 4      B 0.3  2
# 5      B 1.3  2
# 6      C 1.5  3
# 7      C 1.7  3
# 8      C 1.9  3
# 9      A 2.1  4
# 10     A 2.4  4
# 11     B 6.7  5
aggregate(Var ~ ., dat, sum)
#   Group id Var
# 1     A  1 2.9
# 2     B  2 1.6
# 3     C  3 5.1
# 4     A  4 4.5
# 5     B  5 6.7
rleid2 <- function(x) {
  x <- as.vector(x)
  rep(seq_along(rle(x)$values), rle(x)$lengths)
}
rleid2(dat$Group)
# [1] 1 1 1 2 2 3 3 3 4 4 5
set.seed(1)
dat2 <- dat[sample(1:nrow(dat), 1e6, TRUE), ]

identical(data.table::rleid(dat2$Group),
          rleid(dat2$Group))
# [1] TRUE

library('microbenchmark')
microbenchmark(data.table::rleid(dat2$Group),
               rleid(dat2$Group),
               rleid2(dat2$Group), unit = 'relative')


# Unit: relative
#                          expr       min        lq      mean    median        uq       max neval cld
# data.table::rleid(dat2$Group)  1.032777  1.015395  1.005023  1.020923  1.000612 0.8935531   100  a
#             rleid(dat2$Group)  1.000000  1.000000  1.000000  1.000000  1.000000 1.0000000   100  a
#            rleid2(dat2$Group) 35.747987 35.351585 28.600030 34.058992 33.147546 9.8786083   100   b