【问题标题】:How to impute missing values with mean by group and replace existing values如何按组用平均值估算缺失值并替换现有值
【发布时间】:2019-12-19 19:21:52
【问题描述】:

我有一个纵向数据集,其中包含第一次访问时人的身高数据。其他行是空的。 但有时一个人有两种价值观和两种不同的价值观。 我想用组的平均值替换缺失值,并用平均值替换现有值。我试过了:

data$variable <- ave(data$variable, data$group, 
                     FUN = function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))

此代码将缺失值替换为平均高度,但仍保留现有高度。

【问题讨论】:

    标签: r


    【解决方案1】:

    我的理解是缺失值被组替换,对于组中具有重复的 ID,那些特定的 ID 需要具有它们两者的平均值。

    因此,您需要执行两个功能:

    data$variable <- ave(data$variable, data$group, 
                         FUN = function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))
    
    data$variable <- ave(data$variable, data$group, data$ID,
                         FUN = mean)
    

    dplyr 语法中,你会这样做:

    library(dplyr)
    
    data <- data%>%
      group_by(group)%>%
      mutate(variable = coalesce(variable, mean(variable, na.rm = TRUE)))%>%
      group_by(ID, add = T)%>%
      mutate(variable = mean(variable))%>%
      ungroup()
    

    还有data.table:

    library(data.table)
    
    setDT(data)
    data[, variable := ifelse(is.na(variable), mean(variable, na.rm = T), variable), by = group]
    data[, variable := mean(variable), by = .(ID, group)]
    

    【讨论】:

      【解决方案2】:

      在这种情况下,这是一个用每个组(物种)的平均值替换缺失值的示例。诚然不是最优雅的解决方案。

      library(tidyverse)
      
      # creating an example data with NA inserted randomly for 20 values of Petal.Length
      set.seed(4)
      row_with_na <- sample(1:nrow(iris), 20)
      iris[row_with_na, "Petal.Length"] <- NA
      
      # generate the mean of Petal.Length by the Species     
      ref <- iris %>% group_by(Species) %>% summarise(mean_petal_length = mean(Petal.Length, na.rm=TRUE))
      
      # replace the NA based on Species
      
      iris %>% mutate(Petal.Length = ifelse(is.na(Petal.Length) & Species == "setosa", ref[ref$Species == "setosa", "mean_petal_length"],
                                            ifelse(is.na(Petal.Length) & Species == "versicolor", ref[ref$Species == "versicolor", "mean_petal_length"],
                                                   ifelse(is.na(Petal.Length) & Species == "virginica", ref[ref$Species == "virginica", "mean_petal_length"], Petal.Length))))
      

      【讨论】:

      • 不幸的是,我有 1532 个不同的 ID。
      • 哈哈~!这就是为什么我说这不是一个优雅的解决方案。 @Cole 的解决方案非常适合此目的。测试一下。
      猜你喜欢
      • 2019-08-16
      • 2018-02-05
      • 1970-01-01
      • 2012-05-03
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多