【问题标题】:create list column by mapping over data columns and pattern rows通过映射数据列和模式行来创建列表列
【发布时间】:2021-11-01 00:23:30
【问题描述】:

首要问题:

我有我的数据标题,

dat <- tibble(var1 = c("rnw wnd", "rnw wat"),
              var2 = c("elc", NA))

我有另一个数据集,它是一组模式匹配规则,如果 var1、var2 和 combine_rule == T,则分配 grp。

patterns <- tibble(var1_patterns = c("rnw", "wnd", NA),
                   var2_patterns = c("elc", NA, "elc"),
                   combine_rule = c("&", NA, NA),
                   grp = c("elc_rnw", "wnd", "elc"))

我想在dat 中附加一个列表列,其中包含 var1、var2 组合满足规则的所有 grps。

所以结果是:


dat <- tibble(var1 = c("rnw wnd", "rnw wat"),
              var2 = c("elc", NA), 
              grp = c(list(c("elc_rnw", "wnd", "elc")),
                      list(NA))
)

更简单的问题

这就是完整的问题,我意识到这相当多。在第一个实例中,输入如何映射 str_match(var1, var1_pattern) 以创建忽略 var1 和 var2 之间的逻辑关系的列表列会很有帮助。所以结果是:

dat <- tibble(var1 = c("rnw wnd", "rnw wat"),
              var2 = c("elc", NA), 
              grp = c(list( c("elc_rnw", "wnd")), 
                      list("elc_rnw"))
)

我想到了类似映射str_match的东西,

dat %>%
     mutate(grp = map(var1, ~str_match(.x, pattern$var1_pattern)) 

创建一个新的列表列。但我不知道如何映射pattern 的行以创建列表列。有一个循环选项,但我正在尽力避免这种情况!

我还应该补充一点,patterndat 将是函数的参数,所以我(认为我)不能使用 case_when 进行模式匹配。

对于简单问题或总体问题的任何建议将不胜感激。

(抱歉,如果这是重复的,但我没有找到问题,可能是因为我没有恰当地表达问题)

【问题讨论】:

  • 谢谢。现在应该修复了

标签: r purrr


【解决方案1】:

我认为我已经为模式中逻辑“&”的特定情况找到了解决方案。

如果有人对解决此问题的更优雅的方式提出建议,或者有任何其他建议,我们将不胜欢迎。

# Create dat and patterns
dat <- tibble::tibble(var1 = c("rnw wnd", "rnw wat"),
              var2 = c("elc", NA))

patterns <- tibble::tibble(var1_patterns = c("rnw", "wnd", NA),
                   var2_patterns = c("elc", NA, "elc"),
                   combine_rule = c("&", NA, NA),
                   grp = c("elc_rnw", "wnd", "elc"))
    
# function to return logical matches if pattern detected
check_for_matches <- function(var, patterns){

  out <- stringr::str_detect(var, patterns)
  # if var is missing, we want to return F for all matches
  if(is.na(var)){
    out <- replace(out, 1:length(out), F)
    }
  out

}


dat %>%
  #create logicals for detection of var1 and var2 seperately
  dplyr::mutate(var1_check = purrr::map(var1,
                                ~check_for_matches(.x,
                                                   patterns$var1_patterns))) %>%
  dplyr::mutate(var2_check = purrr::map(var2,
                                  ~check_for_matches(.x,
                                                     patterns$var2_patterns))) %>%
  #append the group column
  dplyr::mutate(grp = list(patterns$grp)) %>%
  # unnest because we are working across columns 
  tidyr::unnest(c(var1_check, var2_check, grp)) %>%
  #create logical for joining var1_check and var2_check and accounting for NAs
  dplyr::mutate(joined = dplyr::if_else(is.na(var1_check & var2_check) == F,
                                        var1_check & var2_check,
                                        dplyr::if_else(is.na(var1_check), var2_check,
                                                       var1_check)),
                # if joined T, then grp
                grp = dplyr::if_else(joined, grp, NA_character_)) %>%
  dplyr::select(var1, var2, grp) %>%
  tidyr::nest(data = c(grp))
  

【讨论】:

    猜你喜欢
    • 2023-02-08
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 2018-08-23
    相关资源
    最近更新 更多