Sửa lưu ý: loại bỏ phần gốc của câu trả lời của tôi mà không giải quyết NA điều trị & thêm điểm chuẩn.
concat2 <- function(x) if(all(is.na(x))) NA_character_ else paste(na.omit(x), collapse = ",")
Sử dụng data.table:
setDT(df)[, lapply(.SD, concat2), by = proid, .SDcols = -c("X4")]
# proid X1 X2 X3
#1: 1 zz,cd a,s e,f
#2: 2 ff,ta g,b z,h
#3: 3 NA t e
Sử dụng dplyr:
df %>% group_by(proid) %>% summarise_each(funs(concat2), -X4)
Benchmark, dữ liệu nhỏ hơn trong trường hợp sử dụng thực tế và không đại diện đầy đủ, vì vậy chỉ muốn để có được một ấn tượng như thế nào concat2
so sánh với concat
vv ..
library(microbenchmark)
library(dplyr)
library(data.table)
N <- 1e6
x <- c(letters, LETTERS)
df <- data.frame(
proid = sample(1e4, N, TRUE),
X1 = sample(sample(c(x, NA), N, TRUE)),
X2 = sample(sample(c(x, NA), N, TRUE)),
X3 = sample(sample(c(x, NA), N, TRUE)),
X4 = sample(sample(c(x, NA), N, TRUE))
)
dt <- as.data.table(df)
concat <- function(x){
x <- na.omit(x)
if(length(x)==0){
return(as.character(NA))
}else{
return(paste(x,collapse=","))
}
}
concat2 <- function(x) if(all(is.na(x))) NA_character_ else paste(na.omit(x), collapse = ",")
concat.dplyr <- function(){
df %>% group_by(proid) %>% summarise_each(funs(concat), -X4)
}
concat2.dplyr <- function(){
df %>% group_by(proid) %>% summarise_each(funs(concat2), -X4)
}
concat.data.table <- function(){
dt[, lapply(.SD, concat), by = proid, .SDcols = -c("X4")]
}
concat2.data.table <- function(){
dt[, lapply(.SD, concat2), by = proid, .SDcols = -c("X4")]
}
microbenchmark(concat.dplyr(),
concat2.dplyr(),
concat.data.table(),
concat2.data.table(),
unit = "relative",
times = 10L)
Unit: relative
expr min lq median uq max neval
concat.dplyr() 1.058839 1.058342 1.083728 1.105907 1.080883 10
concat2.dplyr() 1.057991 1.065566 1.109099 1.145657 1.079201 10
concat.data.table() 1.024101 1.018443 1.093604 1.085254 1.066560 10
concat2.data.table() 1.000000 1.000000 1.000000 1.000000 1.000000 10
Kết quả: dữ liệu. Có thể thực hiện nhanh hơn một chút so với dplyr trên dữ liệu mẫu và concat2
nhanh hơn một chút so với concat
. Tuy nhiên, sự khác biệt vẫn còn khá nhỏ trên tập dữ liệu mẫu này.
thử 'setDT (df) [, lapply (.SD, concat), by = proid] 'và xem những gì timings trông giống như – eddi