在 R 中与 FUN = 'c' 或 'list' 聚合

aggregate with FUN = 'c' or 'list' in R

一直在四处寻找,但到目前为止还没有成功。

这是数据框。

> test = data.frame(x = c(1,1,2,2,3,3), y = c('a','b','c','d','e','f'))
> test
  x y
1 1 a
2 1 b
3 2 c
4 2 d
5 3 e
6 3 f

正在寻找一种聚合方法,使具有相同 x 值的 y 形成列表或向量。

类似

  x y
1 1 a,b
2 2 c,d
3 3 e,f

已尝试 'c' 但结果与预期不符

> aggregate(y~x, data = test, FUN = 'c')
  x y.1 y.2
1 1   1   2
2 2   3   4
3 3   5   6

'list' 似乎可行,但它会将字符转换为因子。

> ss = aggregate(y~x, data = test, FUN = 'list')
> class(ss$y[1][[1]])
[1] "factor"
> ss$y[1]
$`1`
[1] a b
Levels: a b c d e f

如有任何意见,我们将不胜感激。

这是一种使用基数 R

的方法
res <-lapply(split(test, test$x), function(xx) data.frame(x=unique(xx$x),
   y=paste(xx$y, collapse=", ")))
do.call(rbind, res)
  x    y
1 1 a, b
2 2 c, d
3 3 e, f

'test' 数据中的 'y' 列是 factor(@BondedDust 提到),因为 data.frame 调用中的默认设置是 stringsAsFactors=TRUE .因此,它不会将 character 转换为 factor。如果我们在创建 data.frame 时使用 stringsAsFactors=FALSE,则 class 将是 character 并且将保持原样。

test = data.frame(x = c(1,1,2,2,3,3), y = c('a','b','c','d','e','f'), 
           stringsAsFactors=FALSE)
res <- aggregate(y~x, data = test, FUN = 'list')
str(res)
#'data.frame':  3 obs. of  2 variables:
#$ x: num  1 2 3
# $ y:List of 3
# ..$ 1: chr  "a" "b"
# ..$ 2: chr  "c" "d"
# ..$ 3: chr  "e" "f"

不是创建 list,另一种方法是 paste 将字符串组合在一起(toStringpaste(., collapse=', ') 的包装器)

aggregate(y~x, data = test, FUN = toString)    

或者我们可以使用 data.table 作为替代方法。我们将 'data.frame' 转换为 'data.table' (setDT(test)),按 'x' 分组,我们 list 'y' 元素。

library(data.table)
setDT(test)[, list(y=list(y)), by = x]

您可以使用 tidyr 中的 nest:

library(tidyr)

nest(test, y)

Source: local data frame [3 x 2]
Groups: <by row>

      x           y
  (dbl)       (chr)
1     1 <S3:factor>
2     2 <S3:factor>
3     3 <S3:factor>

这些 <S3:factor> 确实是您想要的列表:

[[1]]
[1] a b
Levels: a b c d e f

[[2]]
[1] c d
Levels: a b c d e f

[[3]]
[1] e f
Levels: a b c d e f