【问题标题】:Anonymous function for a regex filter正则表达式过滤器的匿名函数
【发布时间】:2020-01-17 09:53:52
【问题描述】:

我有一个 filter() 函数,用于过滤 tibble 中的特定正则表达式。因为我需要多次执行此操作,所以我想编写一个 as_mapper() 函数以得到更短的代码。我该怎么做?

我尝试了以下方法:

adverts <- as_mapper(~!grepl("(xtm)|((k|K)(i|I|1|11)(d|D)(n|N).)|(Ar<e)\\s(you)\\s(in)| 
  (LOAN)|(AR(\\s|\\S)[0-9])|((B|b)(i|1|l)tc.)|(Coupon)|(Plastic.King)|(organs)|(SILI)|(Electric.Cigarette.Machine)",.$value,perl = T)%>% filter)

如果我尝试将此函数添加到 tibble,R 会抛出 C stack usage x is too close to the limit 错误。我怎样才能避免这种情况?

可以使用以下代码生成我要检查的 tibble 之一:

library(tidyverse)
library(rvest)
library(textreadr)

bribe <- read_html(paste("http://ipaidabribe.com/reports/paid?page", 10, sep = "="))
all.nodes <- c(".heading-3 a",".paid-amount span", ".date", ".location", ".transaction a")
test <- map(all.nodes, ~ html_nodes(bribe, .x) %>% html_text()) %>% 
  unlist %>% 
  as_tibble
adverts(test)

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    编辑更短的代码

    你可以写一个不依赖as_mapper的简单的一行函数:

    target_regex <- "(xtm)|((k|K)(i|I|1|11)(d|D)(n|N).)|(Ar<e)\\s(you)\\s(in)| 
    (LOAN)|(AR(\\s|\\S)[0-9])|((B|b)(i|1|l)tc.)|(Coupon)|(Plastic.King)|(organs)|(SILI)|(Electric.Cigarette.Machine)"
    adverts <- function(df, col) df[!grepl(target_regex, df[[col]],perl = T), ]
    test_df %>% adverts(col = "value")
    

    这将只返回 df 中找不到正则表达式的行


    我认为您不需要在这里使用映射器,您可以简单地构建一个普通函数,该函数将一个 tibble、一个目标正则表达式作为输入,并返回该 tibble 并添加一个列,给出grepl 的结果。一种可能是:

    filter_regex <- function(df, regex, col){
        df %>% 
            mutate(found = grepl(pattern = regex, x = df[[col]])) %>% 
            filter(found == TRUE) %>% 
            select(-found)
    }
    test_df <- map(all.nodes, ~ html_nodes(bribe, .x) %>% html_text()) %>%
        unlist %>% 
        as_tibble
    target_regex <- "(xtm)|((k|K)(i|I|1|11)(d|D)(n|N).)|(Ar<e)\\s(you)\\s(in)| 
    (LOAN)|(AR(\\s|\\S)[0-9])|((B|b)(i|1|l)tc.)|(Coupon)|(Plastic.King)|(organs)|(SILI)|(Electric.Cigarette.Machine)"
    
    filter_regex(test_df, target_regex, "value")
    
    > # A tibble: 7 x 1
    >  value                                                                                      
    >  <chr>                                                                                      
    > 1 "\r\n                      Kidney Donor Needed Urgently Needed\r\n                    "    
    > 2 "\r\n                      Kidney Donor Needed Urgetly \r\n                    "           
    > 3 "\r\n                      Urgent Kidney Donor Needed\r\n                    "             
    > 4 "\r\n                      Urgent Kidney Donor Needed\r\n                    "             
    > 5 "\r\n                      Kidney Donor Needed\r\n                    "                    
    > 6 "\r\n                      Kidney Donor Needed\r\n                    "                    
    > 7 "\r\n                      Kidney donation urgently needed in India for 7 CR\r\n  
    

    【讨论】:

    • 这也是我想出的一个想法,但可能不是最方便的解决方案,我想使用匿名函数来完全避免这 10-15 行代码,但只需一个简单的方法as_mapper() 函数。
    • 好的,在这种情况下你仍然不需要as_mapper,只需使用匿名函数即可。我已经编辑了答案以显示示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    • 2016-09-02
    • 2012-12-10
    相关资源
    最近更新 更多