2015-10-31 14 views
7

Ho un set di dati che è simile al seguente:rotolamento concatenazione Testo Data.Table in R

rownum<-c(1,2,3,4,5,6,7,8,9,10) 
name<-c("jeff","jeff","mary","jeff","jeff","jeff","mary","mary","mary","mary") 
text<-c("a","b","c","d","e","f","g","h","i","j") 
a<-data.table(rownum,name,text) 

vorrei aggiungere una nuova colonna di testo che aggiunge dalla colonna precedente rownum e il nome. Il vettore della nuova colonna sarà:

rolltext<-c("a","ab","c","abd","abde","abdef","cg","cgh","cghi","cghij" 

Sono in perdita qui in termini di cosa fare. Per i numeri vorrei solo usare la funzione cumsum, ma per il testo sto pensando che avrei bisogno di un ciclo for o di utilizzare una delle funzioni apply?

risposta

7

Ecco un'idea utilizzando substring().

a[, rolltext := substring(paste(text, collapse = ""), 1, 1:.N), by = name] 

che dà

rownum name text rolltext 
1:  1 jeff a  a 
2:  2 jeff b  ab 
3:  3 mary c  c 
4:  4 jeff d  abd 
5:  5 jeff e  abde 
6:  6 jeff f abdef 
7:  7 mary g  cg 
8:  8 mary h  cgh 
9:  9 mary i  cghi 
10:  10 mary j cghij 

Potremmo essere in grado di accelerare questo un po 'con il pacchetto distringi

library(stringi) 
a[, rolltext := stri_sub(stri_c(text, collapse = ""), length = 1:.N), by = name] 
7

È possibile utilizzare Reduce con l'opzione accumulate:

a[, rolltext := Reduce(paste0, text, accumulate = TRUE), by = name] 

    rownum name text rolltext 
1:  1 jeff a  a 
2:  2 jeff b  ab 
3:  3 mary c  c 
4:  4 jeff d  abd 
5:  5 jeff e  abde 
6:  6 jeff f abdef 
7:  7 mary g  cg 
8:  8 mary h  cgh 
9:  9 mary i  cghi 
10:  10 mary j cghij 

In alternativa, come suggerito @DavidArenburg, costruire ogni riga con sapply:

a[, rolltext := sapply(1:.N, function(x) paste(text[1:x], collapse = '')), by = name] 

Questa è una esecuzione sum , mentre una somma rolling (nel titolo OP) è qualcosa di diverso, almeno in R lingo.

+1

Nizza. Forse anche 'a [, rolltext: = sapply (1: .N, function (x) incolla (text [1: x], collapse = '')), per = nome]' –

+0

Grazie, David, l'ho modificato Il lato negativo di ciò potrebbe essere che richiede più incollare ('sum (seq (.N) -1)' vs '.N-1' con' Reduce'). Questa è la mia intuizione/indovina, comunque. – Frank