2016-02-12 13 views
7

数字の代わりに文字列/文字書式のテキストのRの累積和に相当するものを行う方法を探しています。異なるテキストフィールドを連結する必要があります。文字列のcumsumに相当R

など。データフレーム "df"内:

列Aには入力B列が含まれます。

A  B 
1 banana banana 
2 boats banana boats 
3 are  banana boats are 
4 awesome banana boats are awesome 

は現在、私は次のループ私はもっとエレガント/高速化ソリューションが存在するかどうかを疑問に思う

df$B <- "" 

for(i in 1:nrow(df)) { 
    if (length(df[i-1,"A"]) > 0) { 
     df$B[i] <- paste(df$B[i-1],df$A[i]) 
    } else { 
     df$B[i] <- df$A[i] 
    } 
} 

を経由してこれを解決しています。

+0

を試すことができます! –

+0

パフォーマンスに問題はありますか? – Heroka

+2

私は古典的な「おしゃべり」が現れました[**ここに**](http://stackoverflow.com/questions/24862046/cumulative-pasting-concatenating-values-grouped-by-another-variable-in-r/24864007 #24864007)最初に(可能な重複)。 Cudos to @alexis_laz。 – Henrik

答えて

9
(df$B <- Reduce(paste, as.character(df$A), accumulate = TRUE)) 
# [1] "banana"  "banana boats"  "banana boats are" "banana boats are awesome" 
+1

印象的で、驚くほど速い。 (1000文字列の入力ベクトルで、私の解決法よりも20倍高速) – Heroka

+0

@Heroka Reduceは単にforループです。 – Roland

+0

@Rolandとsapplyですが、私のマシンではReduceが他の回答を吹き飛ばしました。私はそれが 'accumulate = TRUE'だと思います。 – Heroka

4

それは高速です場合、私は知らないが、少なくとも、コードが短い:Rolandsコメントに

sapply(seq_along(df$A),function(x){paste(A[1:x], collapse=" ")}) 

おかげで、私は、これはforループは可能性が珍しい出現箇所の一つであったことに気づきましたそれは私たちに繰り返しインデックスを保存するので便利です。これはOPとは異なり、2から始まり、forループ内のif文が不要になります。

res <- c(NA, length(df1$A)) 
res[1] <- as.character(df1$A[1]) 
for(i in 2:length(df1$A)){ 
    res[i] <- paste(res[i-1],df1$A[i]) 
} 
res 
4

我々はそれがすべてで "CUMSUM" ではありません

i1 <- sequence(seq_len(nrow(df1))) 
tapply(df1$A[i1], cumsum(c(TRUE,diff(i1) <=0)), 
        FUN= paste, collapse=' ') 

それとも

i1 <- rep(seq(nrow(df1)), seq(nrow(df1))) 
tapply(i1, i1, FUN= function(x) 
      paste(df1$A[seq_along(x)], collapse=' '))