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

时间:2015-09-20 02:23:52

标签: r list concatenation aggregate-functions aggregate

到目前为止一直在寻找但没有运气。

这是数据框。

> 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

感谢您的任何评论,谢谢。

3 个答案:

答案 0 :(得分:5)

列' y'在'测试'数据为factor(由@BondedDust提及),data.frame调用中的默认设置为stringsAsFactors=TRUE。因此,它没有将character转换为factor。如果我们在创建stringsAsFactors=FALSE时使用data.frame,则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作为替代方法。我们转换了&#39; data.frame&#39;到&#39; data.table&#39; (setDT(test)),按&#39; x&#39;分组,我们list&#39; y&#39;元件。

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

答案 1 :(得分:3)

这是基础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

答案 2 :(得分:3)

您可以使用nest中的tidyr

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