到目前为止一直在寻找但没有运气。
这是数据框。
> 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
感谢您的任何评论,谢谢。
答案 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
字符串放在一起(toString
是paste(., 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