簡體   English   中英

用基於組的平均值替換 R dataframe 中的 NA,並將其應用於多個列

[英]Replacing NAs in R dataframe with mean based on group and apply the same to multiple columns

我有這個 dataframe。

library(tidyverse)
df <- tibble(
  "group" = c("A", "A", "B", "B"),
  "WC" = c(NA, 2.3, 3.5, 4),
  "Sixltr" = c(3.3, NA, NA, 2.7),
  "Dic" = c(NA, NA, NA, 2.4),
  "I" = c(3.1, 3, 2.7, 1.9),
  "We" = c(4.6, NA, 2.2, NA)
)

我創建了mean_NA_conditional_function function 以用平均值替換NAs (基於某些條件),然后我使用lapply在 dataframe 的所有列上執行相同的操作 - 但是,這並不重要,我也可以簡單地使用常規的意思。

mean_NA_conditional_function <- function(vector) {
  # when NA <= 1 in vector, return the mean of available data in vector
  if (sum(is.na(vector)) <= 1) {return(mean(vector, na.rm = TRUE))}
  # when NA >= 2 in vector, return the sum of available data in vector divided by vector length - 1
  if (sum(is.na(vector)) >= 2) {return((sum(vector, na.rm = TRUE)) / (length(vector) - 1))}
}

#Create the 'NAs_replace_function' function that replaces NAs applying the 'mean_NA_conditional_function'. 
NAs_replace_function <- function(vector) replace(vector, is.na(vector), mean_NA_conditional_function(vector))

#Apply the function 'NAs_replace_function' to selected columns and replace NAs with appropriate mean.
df_after_imputation <- replace(df, TRUE, lapply(df, NAs_replace_function))

到目前為止,這行得通。 但是,我想做的是根據每個值所屬的組(即“A”、“B”)替換NA 我試圖group_by() ,但它沒有用。 不確定我是否做錯了什么。 關於如何解決這個問題的任何想法?

# This doesn't work:
df_after_imputation <- df %>% group_by(group) %>% replace(., TRUE, lapply(df, NAs_replace_function))

您可以使用:

library(dplyr)

df %>%
  group_by(group) %>%
  mutate(across(WC:We, NAs_replace_function)) %>%
  ungroup -> df_after_imputation

df_after_imputation

#  group    WC Sixltr   Dic     I    We
#  <chr> <dbl>  <dbl> <dbl> <dbl> <dbl>
#1 A       2.3    3.3   0     3.1   4.6
#2 A       2.3    3.3   0     3     4.6
#3 B       3.5    2.7   2.4   2.7   2.2
#4 B       4      2.7   2.4   1.9   2.2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM