基于模式的一部分在数据框的列中拆分文本

时间:2017-08-03 15:07:05

标签: r strsplit

使用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::cSplitstringr::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)

2 个答案:

答案 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))

这里的优点是您可以为分割列提供预定义的名称(例如此处taxprob),这些名称可能对下游数据争用有用。 另一方面,关于被接受的答案的有趣之处在于,当数据被分割成的colomns的数量不是预先知道的(或者取决于初始数据帧列的变量)时,它仍将像魅力一样工作。