【问题标题】:How to update values in a dplyr pipe?如何更新 dplyr 管道中的值?
【发布时间】:2020-06-09 19:52:46
【问题描述】:

我想更新新列中的值。

这是我的数据:

people<- c("father", "parents", "father", "children", "girl", "boy", "grand father", "grand mother", "grandparents" ) 
dataset0 <- data.frame(people)
dataset0

然后输出:

father              
parents             
father              
children                
girl                
boy             
grand father                
grand mother                
grandparents

预期输出:

 people           people_update

father            parents   
parents           parents   
father            parents   
children          children
girl              children
boy               children
grand father      grandparents          
grand mother      grandparents      
grandparents      grandparents

我尝试使用replace()

dataset <- dataset0 %>%
   mutate(people_update = replace(people, people =="girl", "children")) %>%
   mutate(people_update = replace(people, people =="boy", "children")) 
 dataset

但这不起作用。第二个mutate() 命令取消了第一个mutate() 命令。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    尝试case_when 指定多个替换。它比多个ifelse 语句更简洁。

    library(dplyr)
    
    dataset <- dataset0 %>%
      mutate(people_update = case_when(
        people %in% c("father", "parents")                            ~ "parents",
        people %in% c("children", "girl", "boy")                      ~ "children",
        people %in% c("grandparents", "grand father", "grand mother") ~ "grandparents",
        TRUE                                                          ~ NA_character_
      ))
    

    【讨论】:

    • 0.5 版本。我只有人员列。
    • 我的是0.7.1。这个case_when 功能是新事物。请更新到最新版本。
    • 如果还是不行,使用多个ifelse语句或者加入其他人建议的方法。
    【解决方案2】:

    这可以通过嵌套的ifelse 语句来处理,即

    library(dplyr)
    
    dataset0 %>% 
      mutate(v1 = ifelse(people %in% c('father', 'mother', 'parents'), 'parents', 
                 ifelse(people %in% c('girl', 'boy', 'children'), 'children', 'grandparents')))
    
    #        people           v1
    #1       father      parents
    #2      parents      parents
    #3       father      parents
    #4     children     children
    #5         girl     children
    #6          boy     children
    #7 grand father grandparents
    #8 grand mother grandparents
    #9 grandparents grandparents
    

    【讨论】:

      【解决方案3】:

      case_when() 或嵌套if_else() 的替代方法是加入转换表map

      library(dplyr)
      dataset0 %>% left_join(map)
      
      Joining, by = "people"
              people people_update
      1       father       parents
      2      parents       parents
      3       father       parents
      4     children      children
      5         girl      children
      6          boy      children
      7 grand father  grandparents
      8 grand mother  grandparents
      9 grandparents  grandparents
      Warning message:
      Column `people` joining factor and character vector, coercing into character vector
      

      map 由下式给出

      map <- tribble(
        ~people, ~people_update,
        "father",            "parents",   
        "parents",           "parents",   
        "children",          "children",
        "girl",              "children",
        "boy",               "children",
        "grand father",      "grandparents",          
        "grand mother",      "grandparents",      
        "grandparents",      "grandparents"
      )
      map
      
      # A tibble: 8 x 2
              people people_update
               <chr>         <chr>
      1       father       parents
      2      parents       parents
      3     children      children
      4         girl      children
      5          boy      children
      6 grand father  grandparents
      7 grand mother  grandparents
      8 grandparents  grandparents
      

      如果需要翻译的项目很少,可以修改代码:

      # define only items to be changed
      map2 <- tribble(
        ~people, ~people_update,
        "father",            "parents",   
        "mother",            "parents",   
        "girl",              "children",
        "boy",               "children",
        "grand father",      "grandparents",          
        "grand mother",      "grandparents"      
      )
      

      请注意,"mother" 已添加到转换表中。

      dataset0 %>% 
        left_join(map2) %>% 
        # copy unchanged items
        mutate(people_update = if_else(is.na(people_update), people, people_update))
      
              people people_update
      1       father       parents
      2      parents       parents
      3       father       parents
      4     children      children
      5         girl      children
      6          boy      children
      7 grand father  grandparents
      8 grand mother  grandparents
      9 grandparents  grandparents
      

      【讨论】:

        【解决方案4】:

        重点是你的第二个mutate,你在x参数处一直使用people而不是people_update

        dataset <- dataset0 %>%
                       mutate(people_update = replace(people, people == "girl", "children")) %>%
                       mutate(people_update = replace(people_update, people == "boy", "children")) 
        dataset
        

        【讨论】:

          猜你喜欢
          • 2020-06-09
          • 2016-01-24
          • 1970-01-01
          • 2014-05-29
          • 2021-11-15
          • 2016-12-05
          • 2018-09-01
          • 2019-11-18
          • 1970-01-01
          相关资源
          最近更新 更多