【问题标题】:Replacing many missing columns in a Data Frame using a function使用函数替换数据框中的许多缺失列
【发布时间】:2021-08-18 21:34:37
【问题描述】:

我有一个包含数百列且缺少值的分类数据集。我正在尝试编写一个可以快速执行此操作的函数,但遇到了问题。这是我到目前为止所做的。非常感谢指针:

df <- data.frame(
  id=c(10, 20, 30, 40, 50,60),
  gender=c('male', 'female', 'female', 'male', 'female', ''),
  mood=c('happy', 'sad', 'happy', 'sad','happy', ''),
  outcome=c(1, 1, 0, 0, 0,1),
  province = c('gp', 'np','ec','', 'wc', 'nw'))

我希望能够为每个变量执行此操作:

print("before")
df %>%
count(gender)

levels(df$gender) <- c(levels(df$gender), "Unknown")

df <- df %>% 
    mutate(gender = replace(gender, gender == "", "Unknown"))

print("after ")
df %>%
count(gender)

我在函数中实现这一点的尝试如下,我有一个函数一次接收一个变量:

valueFiller <- function(myVar){
    print("before")
    df %>%
    count(myVar)

    levels(df$myVar) <- c(levels(df$myVar), "Unknown")

    df <- df %>% 
        mutate(myVar = replace(myVar, myVar == "", "Unknown"))

    print("after ")
    df %>%
    count(myVar)
}

然后我打算以这种方式应用于许多列(但这是一次 1 〜我需要能够一次使用带有变量的列表):

df$mood <-mapply(valueFiller, df$mood)
df

我的功能不起作用。请帮助执行此操作。可能有更好的方法来做到这一点,并且很想听听。

谢谢!

【问题讨论】:

    标签: r dataframe function replace mapply


    【解决方案1】:

    您可以使用forcats 包中的fct_recode,传递一个“命名字符向量,其中名称给出新级别,值给出旧级别”:

    library(forcats)
    
    df <- tibble::tibble(
      id=c(10, 20, 30, 40, 50,60),
      gender=c('male', 'female', 'female', 'male', 'female', ''),
      mood=c('happy', 'sad', 'happy', 'sad','happy', ''),
      outcome=c(1, 1, 0, 0, 0,1),
      province = c('gp', 'np','ec','', 'wc', 'nw'))
    
    forcats::fct_recode(df$province, "Unknown" = "")
    #> [1] gp      np      ec      Unknown wc      nw     
    #> Levels: Unknown ec gp np nw wc
    

    reprex package (v2.0.0) 于 2021 年 5 月 31 日创建

    将其包装在 dplyr::mutate() 调用中可以让您一次将其应用于多个变量:

    library(dplyr)
    
    df <- tibble::tibble(
      id=c(10, 20, 30, 40, 50,60),
      gender=c('male', 'female', 'female', 'male', 'female', ''),
      mood=c('happy', 'sad', 'happy', 'sad','happy', ''),
      outcome=c(1, 1, 0, 0, 0,1),
      province = c('gp', 'np','ec','', 'wc', 'nw'))
    
    
    df %>% 
      mutate(across(c(gender, mood, province),
                    ~ forcats::fct_recode(.x, "Unknown" = "")))
    
    #> # A tibble: 6 x 5
    #>      id gender  mood    outcome province
    #>   <dbl> <fct>   <fct>     <dbl> <fct>   
    #> 1    10 male    happy         1 gp      
    #> 2    20 female  sad           1 np      
    #> 3    30 female  happy         0 ec      
    #> 4    40 male    sad           0 Unknown 
    #> 5    50 female  happy         0 wc      
    #> 6    60 Unknown Unknown       1 nw
    

    reprex package (v2.0.0) 于 2021 年 5 月 31 日创建

    对于较旧的dplyr 版本(v1.0.0 之前),您也可以使用mutate_at(注意:您仍然可以在较新的版本中使用它,但在 v1.0.0 中已被across 取代):

    library(dplyr)
    
    df %>% 
      mutate_at(c("gender", "mood", "province"),
                ~ forcats::fct_recode(.x, "Unknown" = ""))
    
    #> # A tibble: 6 x 5
    #>      id gender  mood    outcome province
    #>   <dbl> <fct>   <fct>     <dbl> <fct>   
    #> 1    10 male    happy         1 gp      
    #> 2    20 female  sad           1 np      
    #> 3    30 female  happy         0 ec      
    #> 4    40 male    sad           0 Unknown 
    #> 5    50 female  happy         0 wc      
    #> 6    60 Unknown Unknown       1 nw
    

    reprex package (v2.0.0) 于 2021-05-31 创建

    【讨论】:

    • 我收到一个错误:警告消息:“包 'forcats' 是在 R 版本 3.6.3 下构建的”cross(c(gender, mood, Province), ~forcats::fct_recode (.x, Unknown = "")): 找不到函数 "across" Traceback: 1. df %>% mutate(across(c(gender, mood, Province), ~forcats::fct_recode(.x, . Unknown = "")))
    • 这是否意味着我需要不同版本的 R 才能成功运行?
    • across 是在 dplyr v1.0.0 中引入的,它又依赖于 R >= 3.3.0。尝试运行install.packages("dplyr") 以安装最新版本。你也可以使用dplyr::mutate_at()(我已经相应地更新了我的答案)。
    • 谢谢哥们。这让我离我想去的地方更近了!
    猜你喜欢
    • 2019-12-02
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2022-06-27
    • 2014-05-09
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多