如何将多列值合并为一列?
How to merge multiple columns values into one column?
我有一个名为 "stemmoutput" 的数据框(见下文):
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 tanaman cabai
2 banget hama sakit tanaman
3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
我想像这样将多列值合并到一列中:
TEXT
1 tanaman cabai
2 banget hama sakit tanaman
3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
我试过这段代码,它有效
stemmoutput$TEXT <- with(stemmoutput, paste(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10, sep=" "))
但有没有其他更高效的方法,而不必一一记下列名?
我也试过下面的代码,但也没有用。
for(i in names(stemmoutput)){
stemmoutput$TEXT <- with(stemmoutput, paste(i, sep=" "))}
尝试do.call
library(stringr)
newdat <- data.frame(TEXT=str_trim(do.call(paste, stemmoutput)),
stringsAsFactors=FALSE)
newdat
# TEXT
#1 tanaman cabai
#2 banget hama sakit tanaman
#3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
如果一列中有多个单词,最好使用 ,
作为分隔符
TEXT <- gsub(', [^A-Za-z]+', '', do.call(paste, c(stemmoutput, sep=', ')))
newdat <- data.frame(TEXT, stringsAsFactors=FALSE)
newdat
# TEXT
#1 tanaman, cabai
#2 banget, hama, sakit, tanaman
#3 koramil, nogosari, melaks, ecek, hama, tanaman, padi, ppl, ds, rambun
这是使用 tidyr
的另一个想法
如果您只想 unite
从 X1
到 X10
的列,您可以这样做:
library(tidyr)
unite(stemmoutput, TEXT, num_range("X", 1:10), sep = " ")
如果要合并 所有 列,请执行以下操作:
unite(stemmoutput, TEXT, everything(), sep = " ")
基准测试
我在基准测试中尝试了这两种方法,因为我怀疑 unite
会比 do.call
快得多,但它们最终相当等效:
df <- data.frame(replicate(10,sample(paste0(
sample(LETTERS[1:10]), collapse = ""), 10e5, replace = TRUE)))
mbm <- microbenchmark(
akrun = data.frame(TEXT=str_trim(do.call(paste, df)), stringsAsFactors=FALSE),
steven = unite(df, TEXT, everything(), sep = " "),
times = 50
)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# akrun 1117.1350 1132.3861 1146.3943 1136.3094 1145.076 1232.5633 50 b
# steven 910.7432 924.0386 927.8614 927.7224 929.649 995.3584 50 a
我有一个名为 "stemmoutput" 的数据框(见下文):
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 tanaman cabai
2 banget hama sakit tanaman
3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
我想像这样将多列值合并到一列中:
TEXT
1 tanaman cabai
2 banget hama sakit tanaman
3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
我试过这段代码,它有效
stemmoutput$TEXT <- with(stemmoutput, paste(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10, sep=" "))
但有没有其他更高效的方法,而不必一一记下列名?
我也试过下面的代码,但也没有用。
for(i in names(stemmoutput)){
stemmoutput$TEXT <- with(stemmoutput, paste(i, sep=" "))}
尝试do.call
library(stringr)
newdat <- data.frame(TEXT=str_trim(do.call(paste, stemmoutput)),
stringsAsFactors=FALSE)
newdat
# TEXT
#1 tanaman cabai
#2 banget hama sakit tanaman
#3 koramil nogosari melaks ecek hama tanaman padi ppl ds rambun
如果一列中有多个单词,最好使用 ,
作为分隔符
TEXT <- gsub(', [^A-Za-z]+', '', do.call(paste, c(stemmoutput, sep=', ')))
newdat <- data.frame(TEXT, stringsAsFactors=FALSE)
newdat
# TEXT
#1 tanaman, cabai
#2 banget, hama, sakit, tanaman
#3 koramil, nogosari, melaks, ecek, hama, tanaman, padi, ppl, ds, rambun
这是使用 tidyr
如果您只想 unite
从 X1
到 X10
的列,您可以这样做:
library(tidyr)
unite(stemmoutput, TEXT, num_range("X", 1:10), sep = " ")
如果要合并 所有 列,请执行以下操作:
unite(stemmoutput, TEXT, everything(), sep = " ")
基准测试
我在基准测试中尝试了这两种方法,因为我怀疑 unite
会比 do.call
快得多,但它们最终相当等效:
df <- data.frame(replicate(10,sample(paste0(
sample(LETTERS[1:10]), collapse = ""), 10e5, replace = TRUE)))
mbm <- microbenchmark(
akrun = data.frame(TEXT=str_trim(do.call(paste, df)), stringsAsFactors=FALSE),
steven = unite(df, TEXT, everything(), sep = " "),
times = 50
)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# akrun 1117.1350 1132.3861 1146.3943 1136.3094 1145.076 1232.5633 50 b
# steven 910.7432 924.0386 927.8614 927.7224 929.649 995.3584 50 a