2014-12-01 8 views
12

Ho un problema con il valore della colonna divisa quando l'elemento della colonna ha un numero diverso di stringhe. Posso farlo in plyr es .:Come estrapolare un numero diverso di stringhe in una determinata funzione della funzione do

library(plyr) 
column <- c("jake", "jane jane","john john john") 
df <- data.frame(1:3, name = column) 
df$name <- as.character(df$name) 
df2 <- ldply(strsplit(df$name, " "), rbind) 
View(df2) 

Come risultato, abbiamo frame di dati con un numero di colonna relativa al numero massimo di punture di dato elemento.

Quando provo a farlo in dplyr, ho usato do funzione:

library(dplyr) 
df2 <- df %>% 
    do(data.frame(strsplit(.$name, " "))) 

ma ottengo un errore:

Error in data.frame("jake", c("jane", "jane"), c("john", "john", "john" : 
arguments imply differing number of rows: 1, 2, 3 

Mi sembra che dovrebbe essere usato rbind funzione, ma Non so dove.

risposta

16

Si verificano problemi perché strsplit() restituisce un elenco che è necessario applicare as.data.frame.list() a ciascun elemento per ottenere il formato corretto richiesto da dplyr. Anche allora richiederebbe ancora un po 'di lavoro per ottenere risultati utilizzabili. Per farla breve, non sembra un'operazione adatta per do().

Penso che potrebbe essere meglio usare separate() da tidyr. Può essere facilmente utilizzato con le funzioni e le catene dplyr. Non è chiaro se si desidera mantenere la prima colonna poiché il risultato ldply per df2 non ce l'ha, quindi l'ho lasciato disattivato.

library(tidyr) 
separate(df[-1], name, 1:3, " ", extra = "merge") 
#  1 2 3 
# 1 jake <NA> <NA> 
# 2 jane jane <NA> 
# 3 john john john 

Si potrebbe anche usare cSplit. E 'anche molto efficiente, in quanto si basa su data.table

library(splitstackshape) 
cSplit(df[-1], "name", " ") 
# name_1 name_2 name_3 
# 1: jake  NA  NA 
# 2: jane jane  NA 
# 3: john john john 

O più precisamente

setnames(df2 <- cSplit(df[-1], "name", " "), names(df2), as.character(1:3)) 
df2 
#  1 2 3 
# 1: jake NA NA 
# 2: jane jane NA 
# 3: john john john 
+1

Ok grazie mille. Ma cosa succede se non sappiamo quante stringhe ci sono in un determinato elemento della colonna? – Nicolabo

+1

Se non sai quante colonne ci saranno, allora userei 'cSplit' perché funziona per te. Bella prima domanda a proposito. Chiaramente chiesto e riproducibile. +1 –

+1

@Nicolabo, puoi prima usare 'stringr :: str_count' per determinare il massimo. no di colonne di cui avresti bisogno e quindi usa 'tidyr :: separate'. Qualcosa del genere - 'len = max (str_count (stringa = df $ nome, modello =" "));' 'vec_names = paste0 (" X ", 1: (len + 1));' 'separato (df ​​[-1], nome, nome_vec, "", extra = "unione"); ' – steadyfish

Problemi correlati