@akrun 的第二个选项很可能是最快的,但您也可以考虑这样的事情:
library(data.table)
na.omit(data.table(
rn = rep(1:nrow(df), ncol(df)),
val = unlist(df, use.names = FALSE)))[, paste(val, collapse = "_"), by = rn]
# rn value
# 1: 1 a_b_b_a
# 2: 2 c_c_d_e
# 3: 3 f_g_h_i
# 4: 4 j_k
基本思想是从“长”data.table 开始,删除 NA 值,然后将剩余的值粘贴在一起。
在此特定示例中,在速度方面,您使用na.omit 会产生很大的不同。
更新
以下是使用相同样本数据(10 万行)I shared at a related question 的一些基准测试。
这些是我测试的功能:
AM <- function() {
na.omit(data.table(
rn = rep(1:nrow(df), ncol(df)),
val = unlist(df, use.names = FALSE)))[, paste(val, collapse = "_"), by = rn]
}
AK <- function() {
df[is.na(df)] <-''
gsub("^_+|_+$|_+(?=_)", "", do.call(paste,c(df, sep="_")), perl=TRUE)
}
RS <- function() {
s <- split(df[!is.na(df)], row(df)[!is.na(df)])
vapply(s, paste, character(1L), collapse = "_", USE.NAMES=FALSE)
}
结果:
microbenchmark(AM(), AK(), RS(), times = 50)
# Unit: milliseconds
# expr min lq mean median uq max neval
# AM() 819.4639 925.1636 1020.5084 979.6239 1118.8065 1384.873 50
# AK() 490.6802 495.5576 559.4551 508.0861 602.8413 1192.798 50
# RS() 1419.8630 1540.5424 1680.6115 1622.7701 1786.9931 2424.541 50