将每列中的一个列折叠/连接/聚合为单个逗号分隔的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"