将每列中的一个列折叠/连接/聚合为单个逗号分隔的string

我想根据两个分组variables在数据框中聚合一列,并用逗号分隔各个值。

这里是一些数据:

data <- data.frame(A = c(rep(111, 3), rep(222, 3)), B = rep(1:2, 3), C = c(5:10)) data # ABC # 1 111 1 5 # 2 111 2 6 # 3 111 1 7 # 4 222 2 8 # 5 222 1 9 # 6 222 2 10 

“A”和“B”是分组variables,“C”是我想折叠成逗号分隔string的variables。 我努力了:

 library(plyr) ddply(data, .(A,B), summarise, test = list(C)) AB test 1 111 1 5, 7 2 111 2 6 3 222 1 9 4 222 2 8, 10 

但是当我试图将testing列转换为character它变成这样:

 ddply(data, .(A,B), summarise, test = as.character(list(C))) # AB test # 1 111 1 c(5, 7) # 2 111 2 6 # 3 222 1 9 # 4 222 2 c(8, 10) 

我怎样才能保持character格式,并用逗号分隔? 例如,第1行应该只是"5,7" ,而不是c(5,7)。

plyr尝试使用toString

 # plyr library(plyr) ddply(data, .(A,B), summarize, C = toString(C)) 

这里有一些额外的select也使用toString

data.table

 # alternative using data.table library(data.table) as.data.table(data)[, toString(C), by = list(A, B)] 

聚合这不使用包:

 # alternative using aggregate from the stats package in the core of R aggregate(C ~., data, toString) 

sqldf

以下是使用sqldf包使用SQL函数group_concat的替代方法:

 library(sqldf) sqldf("select A, B, group_concat(C) C from data group by A, B", method = "raw") 

dplyr一个dplyr替代scheme:

 library(dplyr) data %>% group_by(A, B) %>% summarise(test = toString(C)) %>% ungroup() 

改变你把as.character放在as.character

 > out <- ddply(data, .(A, B), summarise, test = list(as.character(C))) > str(out) 'data.frame': 4 obs. of 3 variables: $ A : num 111 111 222 222 $ B : int 1 2 1 2 $ test:List of 4 ..$ : chr "5" "7" ..$ : chr "6" ..$ : chr "9" ..$ : chr "8" "10" > out AB test 1 111 1 5, 7 2 111 2 6 3 222 1 9 4 222 2 8, 10 

但请注意,每个项目实际上仍然是一个单独的字符,而不是单个string。 也就是说,这不是一个看起来像“5,7”的实际string,而是两个字符“5”和“7”,这些字符在它们之间用逗号显示。

与以下内容进行比较:

 > out2 <- ddply(data, .(A, B), summarise, test = paste(C, collapse = ", ")) > str(out2) 'data.frame': 4 obs. of 3 variables: $ A : num 111 111 222 222 $ B : int 1 2 1 2 $ test: chr "5, 7" "6" "9" "8, 10" > out AB test 1 111 1 5, 7 2 111 2 6 3 222 1 9 4 222 2 8, 10 

基数R中的可比解决scheme当然是aggregate

 > A1 <- aggregate(C ~ A + B, data, function(x) c(as.character(x))) > str(A1) 'data.frame': 4 obs. of 3 variables: $ A: num 111 222 111 222 $ B: int 1 1 2 2 $ C:List of 4 ..$ 0: chr "5" "7" ..$ 1: chr "9" ..$ 2: chr "6" ..$ 3: chr "8" "10" > A2 <- aggregate(C ~ A + B, data, paste, collapse = ", ") > str(A2) 'data.frame': 4 obs. of 3 variables: $ A: num 111 222 111 222 $ B: int 1 1 2 2 $ C: chr "5, 7" "9" "6" "8, 10"