使用来自strsplit的长度不等的ldply

时间:2015-03-21 22:31:00

标签: r

我正在尝试根据某些分隔符将数据框列拆分为多个列。我在这个网站上找到了各种答案,我正在努力寻找不同的工作方式。我遇到了ldply的问题。问题是strsplit的输出是不同长度的元素列表。以下是一些示例数据,有效的内容以及我正在尝试ldply的内容。

FirstName <- c("a,b", "c d", "e, f", "gh")
OtherInfo <- c(1:4)
df <- data.frame(FirstName, OtherInfo, stringsAsFactors = FALSE)
print(df)

#Solution with cSplit
library(splitstackshape)
cs <- cSplit(df, "FirstName", "[, ]+", fixed = FALSE)


#Solution with strsplit and as.data.frame
#Feels like a hack, and I have "gh" repeated
#Question: Is there a better way using a similar approach?
df2 <- t(as.data.frame(strsplit(df$FirstName, "[, ]+", fixed = FALSE)))
row.names(df2) <- NULL


#Question: Solution with strsplit and plyr
library(plyr)
list1 <- strsplit(df$FirstName, "[, ]+", fixed = FALSE)
df3 <- ldply(list1)

错误:

#Error in list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor) : 
#   Results do not have equal lengths

我写了这个修补程序来插入NA值,但它感觉不是最好的方法。还有更好的方法吗?

MAX = max(sapply(list1, length))

func1 <- function(x, MAX) {
    vec <- c(x, rep(NA, MAX-length(x)))
    return(vec)    
}

list2 <- lapply(list1, func1, MAX = MAX)
list2

df3.1 <- ldply(list2)

1 个答案:

答案 0 :(得分:1)

这是dplyr的一个快速解决方案。

library(dplyr)

df4 <- df %>%
  mutate( parts = strsplit(FirstName, "[, ]+", fixed=FALSE) ) %>% 
  group_by( FirstName ) %>%
  do(  data.frame( 
    { 
      idx <- 1:length(.$parts[[1]])
      lst <- lapply(idx,
                    function(x) .$parts[[1]][x])
      names(lst) <- lapply(idx,
                           function(x) paste("Firstname",x,sep="") )

      (lst)
    } , stringsAsFactors=FALSE)
  ) %>% 
  inner_join(df,by="FirstName")

print(df4)

对于提供的示例,我得到:

Source: local data frame [4 x 4]
Groups: FirstName

  FirstName Firstname1 Firstname2 OtherInfo
1       a,b          a          b         1
2       c d          c          d         2
3      e, f          e          f         3
4        gh         gh         NA         4

解决方案的逻辑如下:
1.将每个名字拆分成一个部分列表
2.对于每个FirstName,创建一个新的data.frame,例如数据来自零件,但变量名称是FirstName1,FirstName2等。 3.将数据集合并回原始数据集,以便将OtherInfo重新放入其中