2014-12-01 19 views
12

Tôi có một vấn đề với giá trị cột chia khi yếu tố của cột có số lượng khác nhau của chuỗi. Tôi có thể làm điều đó trong plyr ví dụ:Làm thế nào để strsplit số lượng khác nhau của chuỗi trong cột nhất định bằng cách làm chức năng

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) 

Kết quả là, chúng tôi có khung dữ liệu liên quan đến số lượng tối đa các phần tử đã cho trong phần tử đã cho.

Khi tôi cố gắng làm điều đó trong dplyr, tôi sử dụng do chức năng:

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

nhưng tôi nhận được một lỗi:

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

Dường như với tôi rằng nó nên được sử dụng rbind chức năng nhưng Tôi không biết ở đâu.

Trả lời

16

Bạn đang gặp sự cố vì strsplit() trả về danh sách mà sau đó chúng tôi cần áp dụng as.data.frame.list() cho mỗi thành phần để đưa nó vào đúng định dạng mà dplyr yêu cầu. Thậm chí sau đó nó vẫn sẽ đòi hỏi một chút công việc để có được kết quả có thể sử dụng. Dài câu chuyện ngắn, nó không có vẻ giống như một hoạt động phù hợp cho do().

Tôi nghĩ bạn nên sử dụng separate() từ tidyr. Nó có thể dễ dàng được sử dụng với các chức năng và dây chuyền dplyr. Không rõ liệu bạn có muốn giữ cột đầu tiên kể từ kết quả ldply của bạn cho df2 không có nó, vì vậy tôi đã tắt nó.

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 

Bạn cũng có thể sử dụng cSplit. Nó cũng rất hiệu quả vì nó dựa trên 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 

Hoặc cụ thể hơn

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

nhờ Ok rất nhiều. Nhưng nếu chúng ta không biết có bao nhiêu chuỗi trong thành phần của cột? – Nicolabo

+1

Nếu bạn không biết có bao nhiêu cột sẽ có, thì tôi sẽ sử dụng 'cSplit' vì nó làm việc cho bạn. Nice câu hỏi đầu tiên bằng cách này. Yêu cầu và tái sản xuất rõ ràng. +1 –

+1

@Nicolabo, Trước tiên bạn có thể sử dụng 'stringr :: str_count' để xác định giá trị CPC không có cột nào bạn cần và sau đó sử dụng 'tidyr :: tách biệt'. Một cái gì đó như thế này - 'len = max (str_count (string = df $ name, pattern =" "));' 'vec_names = paste0 (" X ", 1: (len + 1)); ' ' riêng biệt (df ​​[-1], tên, vec_names, "", thêm = "hợp nhất"); ' – steadyfish

Các vấn đề liên quan