使用R我试图将具有指定分隔符的列中的文本拆分为总是两个新列。下面是一个示例数据框:
repdf <- data.frame(a=c("abc(100)","def(95)","ghi(100)","j_(klm)(100)"),b=c("abc(100)","def(95)","ghi(100)","j_(klm)(100)"))
简单来说,我想在每个开括号中拆分“(”,但只有后跟一个数字,但不丢失数字。即所需的结果应如下所示:
a1 a2 b1 b2
abc 100) abc 100)
def 95) def 95)
ghi 100) ghi 100)
j_(klm) 100) j_(klm) 100)
我尝试使用splitstackshape::cSplit
和stringr::str_split_fixed
无效。
cSplit(repdf,c("a","b"),"(")
每个分裂{(“
a_1 a_2 a_3 b_1 b_2 b_3
1: abc 100) NA abc 100) NA
2: def 95) NA def 95) NA
3: ghi 100) NA ghi 100) NA
4: j_ klm) 100) j_ klm) 100)
cSplit(repdf,c("a","b"),"\\(([0-9])",fixed=FALSE)
删除第一个数字,如果可以使用\1
将捕获添加到第二个组,那将是不错的,但遗憾的是它不是。
a_1 a_2 b_1 b_2
1: abc 00) abc 00)
2: def 5) def 5)
3: ghi 00) ghi 00)
4: j_(klm) 00) j_(klm) 00)
as.data.frame(lapply(repdf,function(x)str_split_fixed(x,"\\(",n=2)))
允许我确实只分成2列,但当然只进行第一场比赛:
a.1 a.2 b.1 b.2
1 abc 100) abc 100)
2 def 95) def 95)
3 ghi 100) ghi 100)
4 j_ klm)(100) j_ klm)(100)
答案 0 :(得分:3)
这是一个先行派上用场......本质上我们寻找(
后面跟着一个数字\\d
,但是前瞻不会使用数字进行分割。
do.call(cbind, lapply(repdf, function(x){
do.call(rbind, strsplit(as.character(x), "\\((?=\\d)", perl = TRUE))
}))
# [,1] [,2] [,3] [,4]
# [1,] "abc" "100)" "abc" "100)"
# [2,] "def" "95)" "def" "95)"
# [3,] "ghi" "100)" "ghi" "100)"
# [4,] "j_(klm)" "100)" "j_(klm)" "100)"
答案 1 :(得分:0)
受@ Konrad建议的启发,我发现以下内容与tidyr::extract
一起使用,但我需要使用它的&#39;标准评估版tidyr::extract_
:
do.call(cbind, lapply(seq_along(repdf),
function(df, i){
tidyr::extract_(data=df[i], col = names(df[i]),
into=c(paste0("tax",i),paste0("prob",i)),
regex = "(.*)\\((?=\\d)(.*)",perl=TRUE)}, df=repdf))
这里的优点是您可以为分割列提供预定义的名称(例如此处tax
和prob
),这些名称可能对下游数据争用有用。
另一方面,关于被接受的答案的有趣之处在于,当数据被分割成的colomns的数量不是预先知道的(或者取决于初始数据帧列的变量)时,它仍将像魅力一样工作。