2015-05-16 5 views
3

У меня есть фрейм данных под названием «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=" "))} 

ответ

2

Попробуйте 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 
+1

это работает, большое спасибо – Ihda

+1

@lhda Спасибо за обратную связь – akrun

1

Вот еще одна идея, с помощью 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 
) 

enter image description here

# 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 
+0

я думал, что без вызова 'все () ', должен вставлять целые столбцы, но на самом деле это необходимо – akrun

+0

Да, я тоже так подумал :-) Интересно, как быстро это происходит против' do.call' –

Смежные вопросы