我有一个如下数据框。我想将最后一列拆分为2.拆分需要根据唯一的第一列完成:其余的列不重要。
在新数据框中,将有4列。第3列为(a,b,d),第4列为(1,2:3,3:4:4)
有什么建议吗?我的代码的第4行不起作用:(。我可以使用全新的解决方案或对第4行进行更正
employee <- c('John Doe','Peter Gynn','Jolie Hope')
salary <- c(3, 2, 1)
df <- data.frame(employee, salary, originalColumn = c("a :1", "b :2:3", "d: 3:4:4"))
as.data.frame(do.call(rbind, strsplit(df,":")))
-------------------- UPDATE1
以下解决方案效果很好。但我需要一个修改过的解决方案,因为我刚刚意识到第3列中的某些单元格不会出现&#34;:#34;。在这种情况下,我希望该单元格中的文本在拆分该列
后仅显示在第一列中employee <- c('John Doe','Peter Gynn','Jolie Hope')
salary <- c(3, 2, 1)
df <- data.frame(employee, salary, originalColumn = c("a :1", "b", "d: 3:4:4"))
答案 0 :(得分:5)
您可以使用cSplit
。在您更新的数据框中,
library(splitstackshape)
cSplit(df, "originalColumn", sep = ":{1}")
# employee salary originalColumn_1 originalColumn_2
# 1: John Doe 3 a 1
# 2: Peter Gynn 2 b NA
# 3: Jolie Hope 1 d 3:4:4
在原始数据框中,
df1 <- data.frame(employee, salary,
originalColumn = c("a :1", "b :2:3", "d: 3:4:4"))
cSplit(df1, "originalColumn", sep = ":{1}")
# employee salary originalColumn_1 originalColumn_2
# 1: John Doe 3 a 1
# 2: Peter Gynn 2 b 2:3
# 3: Jolie Hope 1 d 3:4:4
注意:我使用splitstackshape
版本1.4.2。我相信sep
参数已从版本1.4.0更改
答案 1 :(得分:2)
您可以使用extract
中的tidyr
将originalColumn
分割为two
列。在下面的代码中,我创建了3列并从结果中删除了一个不需要的列。
library(tidyr)
pat <- "([^ :])( ?:|: ?|)(.*)"
extract(df, originalColumn, c("Col1", "ColN", "Col2"), pat)[,-4]
# employee salary Col1 Col2
#1 John Doe 3 a 1
#2 Peter Gynn 2 b 2:3
#3 Jolie Hope 1 d 3:4:4
使用更新的df
,(为了更好地识别 - df1
)
extract(df1, originalColumn, c("Col1", "ColN", "Col2"), pat)[,-4]
# employee salary Col1 Col2
#1 John Doe 3 a 1
#2 Peter Gynn 2 b
#3 Jolie Hope 1 d 3:4:4
或者未在column
df
extract(df, originalColumn, c("Col1", "Col2"), "(.)[ :](.*)") %>%
mutate(Col2= gsub("^\\:", "", Col2))
# employee salary Col1 Col2
#1 John Doe 3 a 1
#2 Peter Gynn 2 b 2:3
#3 Jolie Hope 1 d 3:4:4
根据df
中的模式,以下代码也有效。此处,用于提取第一列的regex
为(.)
。点是字符串开头的单个元素,括号内将为Col1
提取。然后,丢弃第一个后面的.{2}
两个元素,括号(.*)
中的其余元素构成Col2
。
extract(df, originalColumn, c("Col1", "Col2"), "(.).{2}(.*)")
# employee salary Col1 Col2
#1 John Doe 3 a 1
#2 Peter Gynn 2 b 2:3
#3 Jolie Hope 1 d 3:4:4
或使用strsplit
as.data.frame(do.call(rbind, strsplit(as.character(df$originalColumn), " :|: ")))
# V1 V2
#1 a 1
#2 b 2:3
#3 d 3:4:4
对于df1
,这是使用strsplit
lst <- strsplit(as.character(df1$originalColumn), " :|: ")
as.data.frame(do.call(rbind,lapply(lst,
`length<-`, max(sapply(lst, length)))) )
# V1 V2
#1 a 1
#2 b <NA>
#3 d 3:4:4
答案 2 :(得分:1)
你很亲密,这是一个解决方案:
library(stringr)
df[, c('Col1','Col2')] <- do.call(rbind, str_split_fixed(df$originalColumn,":",n=2))
df$originalColumn <- NULL
employee salary Col1 Col2
1 John Doe 3 a 1
2 Peter Gynn 2 b 2:3
3 Jolie Hope 1 d 3:4:4
注意:
stringr::str_split()
优于base::strsplit()
,因为您不必执行as.character()
,并且您希望将n=2
参数限制为仅限于{{1}}第一个&#39;:&#39;