代码之家  ›  专栏  ›  技术社区  ›  Al14

使用apply从数据帧中提取括号内容

  •  0
  • Al14  · 技术社区  · 7 年前

    我只想提取括号内的内容,如果使用向量,效果会很好(下面的示例):

    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]]))
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Rich Scriven    7 年前

    你不需要 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() 结束 应用() 因为数据帧是一个列表。

    abc[] <- lapply(abc, sub, pattern = ".*\\((.+)\\).*", replacement = "\\1")
    

    强制由隐式执行 sub() ,所以从因素开始不是问题。

        2
  •  1
  •   denis    7 年前

    它按照您告诉他的方式执行,即只为每列获取regmatches列表的第一个元素。我建议使用 str_extract 从stringr软件包中,可以得到一个向量,并且更易于编写和使用:

    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    
    
        3
  •  0
  •   Jan    7 年前

    使用 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"
    

    总是选第二组。

    推荐文章