【问题标题】:Replacing row elements in a column based on row elements from another column in Tidyverse根据 Tidyverse 中另一列的行元素替换列中的行元素
【发布时间】:2019-11-23 17:17:14
【问题描述】:

您好,这是我在堆栈溢出中的第一篇文章,如果格式不正确并且之前已被问过,我深表歉意 - 我无法找到解决方案。

我正在尝试根据另一列的某些条件替换一列中的某些字符串。我有以下数据框:

> df
# A tibble: 14 x 3
   Group1         Group2          Group3               
   <chr>          <chr>           <chr>                
 1 MOBILES        MOBILES - CORE  IOT                  
 2 MOBILES        MOBILES - CORE  IOT_Vas                  
 3 MOBILES        MOBILES - CORE  IOT_Vas              
 4 Data & IP      Data & IP       IP WAN               
 5 Data & IP      Data & IP       Internet Solutions   
 6 Data & IP      Data & IP       Internet Solutions   
 7 MOBILES        IOT             M2M                  
 8 MOBILES        IOT             M2M                  
 9 MOBILES        IOT             M2M VAS              
10 MOBILES        IOT             M2M VAS              
11 Cloud Services Cloud Services  Professional Services
12 Cloud Services Cloud Services  Professional Services
13 Mobiles        MOBILES - CORE  MOBILES - CORE       
14 Mobiles        MOBILES - Voice MOBILES - Voice 

我试图实现的是,如果“Group 3”包含字符串 IOT,则“Group 1”中的值 = IOT,如果“Group 3”包含 M2M,则值“Group 1”=M2M。否则第 1 组中的值保持不变。

我对堆栈溢出和 R tidyverse 比较陌生,但我无法找到解决我的问题的方法。我已经尝试过 str_replace 和 mutate_at 但是当我基于 2 个不同的元素进行替换时,我无法弄清楚如何做到这一点。

生成的数据框应如下所示:

> df
# A tibble: 14 x 3
   Group1         Group2          Group3               
   <chr>          <chr>           <chr>                
 1 IOT            MOBILES - CORE  IOT                  
 2 IOT            MOBILES - CORE  IOT                  
 3 IOT            MOBILES - CORE  IOT_Vas              
 4 Data & IP      Data & IP       IP WAN               
 5 Data & IP      Data & IP       Internet Solutions   
 6 Data & IP      Data & IP       Internet Solutions   
 7 M2M            IOT             M2M                  
 8 M2M            IOT             M2M                  
 9 M2M            IOT             M2M VAS              
10 M2M            IOT             M2M VAS              
11 Cloud Services Cloud Services  Professional Services
12 Cloud Services Cloud Services  Professional Services
13 Mobiles        MOBILES - CORE  MOBILES - CORE       
14 Mobiles        MOBILES - Voice MOBILES - Voice

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    这是tidyverse 的一种方式-

    df %>% 
      mutate(
        Group1 = case_when(
          str_detect(Group3, "IOT") ~ "IOT",
          str_detect(Group3, "M2M") ~ "M2M",
          TRUE ~ Group1
        )
      )
    

    您也可以在基础 R 中使用 ifelsegrepl 执行此操作 -

    df$Group1 <- ifelse(grepl("IOT", df$Group3), "IOT",
                        ifelse(grepl("M2M", df$Group3), "M2M", df$Group1)
                        )
    

    【讨论】:

      【解决方案2】:

      我试图通过创建group1 来复制您的数据框,该group1 将根据group3 的值进行更改。我创建了一个 for 循环,如果在 group3 中检测到其中任何一个字符串,则将 group1 更改为“M2M”或“IOT”,但如果没有找到任何字符串,则 group1 值保持不变。

      df <- data.frame(group1 = c("TEST", "TEST", "TEST", "TEST", "TEST"),
                       group3 = c("M2M", "DATA AND IP", "IOT", "M2M VAS", "IOT MORETEXT"),
                       stringsAsFactors = FALSE)
      
      # loop through rows in df
      for  (i in 1:nrow(df)) {
          # is the string "M2M" in group3?
          if (str_detect(df$group3[i], "M2M")) {
            # if so reassign group1 to M2M
            df$group1[i] <- "M2M"
          # use the same logic, but with the string "IOT"
          } else if (str_detect(df$group3[i], "IOT")) {
            df$group1[i] <- "IOT"
          } else {
            # otherwise keep group1 the same
            df$group1[i] <- df$group1[i]
          }
      }
      

      希望对您有所帮助,我很乐意回答任何进一步的问题或提供澄清!

      【讨论】:

      • str_detect 是矢量化的,所以你不需要循环
      猜你喜欢
      • 1970-01-01
      • 2018-08-19
      • 2019-02-13
      • 1970-01-01
      • 2022-01-17
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      相关资源
      最近更新 更多