【问题标题】:flag specific pattern using string r使用字符串 r 标记特定模式
【发布时间】:2019-11-12 04:41:09
【问题描述】:

我正在处理一个需要标记所有以“C13.xxx”开头的特定代码的数据集。列中还有其他树代码,所有树代码分隔如下:“C13.xxx|B12.xxx” - 所有树代码中都有句点。但是数据集还有其他变量导致我的字符串 r 函数标记不是树代码的字符。示例:

library(tidyverse)

# test data
test <- tribble(
  ~id, ~treecode, ~contains_c13_xxx,
  #--|--|----
  1, "B12.123|C13.234.432|A11.123", "yes",
  2, "C12.123|C13039|", "no"
)

# what I tried 
test  %>% mutate(contains_C13_error = ifelse(str_detect(treecode, "C13."), 1, 0))

# code above is flagging both id's as containing C13.xxx

在 id 2 中,有一个以 C13 开头的变量,但它不是树代码(所有树代码都有句点)。 contains_c13_xxx 变量是我希望代码生成的。在字符串检测函数中,我指定了句点,所以我不确定这里出了什么问题。

【问题讨论】:

    标签: r text tidyverse stringr


    【解决方案1】:

    棘手的部分是同一列中有多个树代码,带有分隔符,很难标记。我们可以将每个treecode 放入单独的行中,然后检查我们需要的代码。使用来自tidyrseparate_rows

    library(dplyr)
    
    test %>%
      tidyr::separate_rows(treecode, sep = "\\|") %>%
      group_by(id) %>%
      summarise(contains_C13_error = any(startsWith(treecode, "C13.")),
                treecode = paste(treecode, collapse = "|"))
    
    # A tibble: 2 x 3
    #     id contains_C13_error treecode                   
    #  <dbl> <lgl>              <chr>                      
    #1     1 TRUE               B12.123|C13.234.432|A11.123
    #2     2 FALSE              C12.123|C13039|         
    

    这是假设可能存在不带点的模式“C13”的代码。如果treecode 总是有"C13" 后跟一个点,那么只需在正则表达式中转义点就可以了。

    【讨论】:

      【解决方案2】:

      基础 R 解决方案:

      # Split on the | delim: 
      
      split_treecode <- strsplit(df$treecode, "[|]")
      
      # Roll out the ids the number of times of each relevant treecode: 
      
      rolled_out_df <- data.frame(id = rep(df$id, sapply(split_treecode, length)), tc = unlist(split_treecode))
      
      # Test whether or not string contains "C13" 
      
      rolled_out_df$contains_c13_xxx <- grepl("C13.", rolled_out_df$tc, fixed = T)
      
      # Does the id have an element containing "C13" ? 
      
      rolled_out_df$contains_c13_xxx <- ifelse(ave(rolled_out_df$contains_c13_xxx,
      
                                                   rolled_out_df$id,
      
                                                   FUN  = function(x){as.logical(sum(x))}), "yes", "no")
      
      # Build back orignal df: 
      
      df <- merge(df[,c("id", "treecode")], unique(rolled_out_df[,c("id", "contains_c13_xxx")]), by = "id")
      

      数据:

      df <- 
        structure(
        list(
          id = c(1, 2),
          treecode = c("B12.123|C13.234.432|A11.123",
                       "C12.123|C13039|"),
          contains_c13_xxx = c("yes", "no")
        ),
        row.names = c(NA,-2L),
        class = "data.frame"
      )
      

      【讨论】:

        猜你喜欢
        • 2023-03-17
        • 2022-12-18
        • 1970-01-01
        • 1970-01-01
        • 2016-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多