【问题标题】:How to replace values of multiple columns with other columns within the same dataframe?如何用同一数据框中的其他列替换多列的值?
【发布时间】:2023-01-24 19:05:49
【问题描述】:

我想从其他列更新多列的值。

test <- data.frame(old1 = c(NA,NA,NA),
                   old2 = c(NA,NA,NA),
                   old3 = c(NA,NA,NA),
                 upd1 = c('1','2','3'),
                 upd2 = c('a','b','c'),
                 upd3 = c('I','II','III')
                 )

我想用upd1old2upd2等值更新列old1。一种方法是一个一个地做,例如在mutate(...)中为每一列使用ifelse。但这并不理想,因为列数超过 100。我想要这样的东西:

test %>% 
  mutate(across(.cols = c(1:3),  ~replace(., is.na(.), c(upd1)) #this is wrong though.
                )
         )

这会使用列 upd1 的值更新所有列,但它不能接受 replace 或 ifelse 函数中的多个列。也许 for 循环可能有效,但我是新手,不具备循环方面的专业知识。

另一种方法是将数据帧一分为二,分别使用merge()aggregate()函数。但它会更改某些列的类型并将日期列的值更改为其他格式。

请问有什么 tidyverse 解决方案吗?

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    使用 dplyr::cur_columnget 你可以这样做:

    library(dplyr, warn=FALSE)
    
    test %>%
      mutate(across(
        .cols = starts_with("old"),
        ~ coalesce(.x, get(gsub("^old", "upd", cur_column())))
      ))
    #>   old1 old2 old3 upd1 upd2 upd3
    #> 1    1    a    I    1    a    I
    #> 2    2    b   II    2    b   II
    #> 3    3    c  III    3    c  III
    

    【讨论】:

      【解决方案2】:

      您可以使用来自 dplyoveracross2

      library(dplyover)
      test %>% 
        mutate(across2(starts_with("old"), starts_with("upd"),
                       ~ ifelse(is.na(.x), .y, .x), 
                       .names = "{xcol}"))
      
        old1 old2 old3 upd1 upd2 upd3
      1    1    a    I    1    a    I
      2    2    b   II    2    b   II
      3    3    c  III    3    c  III
      

      【讨论】:

        猜你喜欢
        • 2019-10-03
        • 1970-01-01
        • 2014-02-06
        • 2020-10-21
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 2019-12-13
        • 1970-01-01
        相关资源
        最近更新 更多