我正在尝试根据某些分隔符将数据框列拆分为多个列。我在这个网站上找到了各种答案,我正在努力寻找不同的工作方式。我遇到了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)
答案 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重新放入其中