我想只提取括号内的内容,如果我使用向量(下面的例子),这种方法效果很好:
j<-"[8] Q(+.98)"
gsub("[\\(\\)]", "", regmatches(j, gregexpr("\\(.*?\\)", j))[[1]])
现在我想使用apply在数据帧的多个列中运行上面的代码。以下是我所做的不起作用。
a<-c("[7] C(+57.02)", "[11] C(+57.02)", NA, NA)
b<- c("[16] C(+57.02)", NA, NA,NA)
c<-c("[9] Q(+.98)" , "[13] Q(+.98)" , "[14] C(+57.02)",NA)
abc<-as.data.frame(rbind(a,b,c))
abc_in<-apply(abc, 2, function(x)
gsub("[\\(\\)]", "", regmatches(x, gregexpr("\\(.*?\\)", x))[[1]]))
答案 0 :(得分:2)
您不需要apply()
或任何套餐。由于我们在整个数据框架上运行,我们可以先将其强制转换为矩阵,然后使用sub()
。
sub(".*\\((.+)\\).*", "\\1", as.matrix(abc))
# V1 V2 V3 V4
# a "+57.02" "+57.02" NA NA
# b "+57.02" NA NA NA
# c "+.98" "+.98" "+57.02" NA
这会给你一个矩阵。如果需要保留数据框结构,那么
abc[] <- sub(".*\\((.+)\\).*", "\\1", as.matrix(abc))
当然,您可以循环数据框列。但是为此,我会使用lapply()
而不是apply()
,因为数据框是一个列表。
abc[] <- lapply(abc, sub, pattern = ".*\\((.+)\\).*", replacement = "\\1")
强制是由sub()
隐式完成的,所以从因素开始不是问题。
答案 1 :(得分:1)
它按照你告诉他的方式执行,即只为每列的regmatches列表中的第一个元素。我建议使用来自stringr包的str_extract
,它会给出一个向量作为结果,并且更容易编写和使用:
library(stringr)
abs_in <- apply(abc,2,function(x){ gsub("[\\(\\)]", "",str_extract(x,"\\(.*?\\)"))})
> abs_in
V1 V2 V3 V4
[1,] "+57.02" "+57.02" NA NA
[2,] "+57.02" NA NA NA
[3,] "+.98" "+.98" "+57.02" NA
答案 2 :(得分:0)
另外,使用stringr
时,您需要在绑定数据帧时指定stringsAsFactors = FALSE
:
abc<-as.data.frame(rbind(a,b,c), stringsAsFactors = FALSE)
library(stringr)
regex <- "\\(([^()]+)\\)"
str_match_all(abc, regex)
这会产生
[[1]]
[,1] [,2]
[1,] "(+57.02)" "+57.02"
[2,] "(+57.02)" "+57.02"
[3,] "(+.98)" "+.98"
[[2]]
[,1] [,2]
[1,] "(+57.02)" "+57.02"
[2,] "(+.98)" "+.98"
[[3]]
[,1] [,2]
[1,] "(+57.02)" "+57.02"
[[4]]
[,1] [,2]
[1,] "(NA, NA, NA)" "NA, NA, NA"
总是选择第二组。