You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中按州子集均值替换DataFrame中的NA值

问题描述

原始数据

head(df)
#>    county state_abr population unemp health_ins poverty SNAP no_comp no_internet home_broad broad_num broad_avail broad_cost price_bbn
#> 1 Autauga        AL      55869   2.7        7.1    15.4 12.7      NA        20.9       78.9         0         0.0   67.32586     35.00
#> 2 Baldwin        AL     223234   2.7       10.2    10.6  7.5      NA        21.3       78.1         0         0.0   67.32586     35.00
#> 3 Barbour        AL      24686   3.8       11.2    28.9 27.4      NA        38.9       60.4         4        99.2   74.99000     35.00
#> 4    Bibb        AL      22394   3.1        7.9    14.0 12.4     23.7        33.8       66.1         0         0.0   67.32586     35.00
#> 5  Blount        AL      57826   2.7       11.0      NA  9.5     21.3          NA       68.5         0         0.0   67.32586     35.00
#> 6 Bullock        AL      10101   3.6       10.8    31.4 25.9     27.1        40.1       58.9         1        40.1   57.99000     71.95

tail(df)
#>     county state_abr population unemp health_ins poverty SNAP no_comp no_internet home_broad broad_num broad_avail broad_cost price_bbn
#> 1 Sublette        WY       9831   4.4       13.4     8.4  2.2      5.4        17.5       81.7         3        19.5      59.65     35.00
#> 2 Sweetwater        WY      42343   3.9       12.0    12.0  5.8      7.7        16.1       82.4         5        95.1      63.30     35.00
#> 3    Teton        WY      23464   2.7       10.0     7.1  2.1      4.2        13.6       85.9         6        96.0      69.99     35.00
#> 4    Uinta        WY      20226   3.9       12.2    12.5  7.1      6.1        11.5       88.2         5        73.9      63.30     35.00
#> 5 Washakie        WY       7805   3.9       15.4    12.4  4.9     12.1        21.5       78.3         5        86.1      64.36     35.00
#> 6   Weston        WY       6927   2.9       13.3    17.4  4.7     13.8        26.1       73.3         2        52.0      66.67     35.00

需求

需要按state_abr(州缩写)分组,计算每个州内各数值列的均值,并用该均值填充对应州内该列的NA值,而非使用整列的全局均值。例如AL州no_comp列的NA,仅用AL州该列的均值填充。

解决方案

方法1:使用dplyr包(tidyverse生态)

这是最常用的tidy风格写法,代码简洁易读:

library(dplyr)

df_filled <- df %>%
  group_by(state_abr) %>%
  mutate(across(where(is.numeric), ~ifelse(is.na(.), mean(., na.rm = TRUE), .))) %>%
  ungroup()

代码说明:

  • group_by(state_abr):按州分组
  • across(where(is.numeric), ...):对所有数值列应用后续操作
  • ifelse(is.na(.), mean(., na.rm = TRUE), .):如果当前值是NA,用该组该列的均值(忽略NA)替换,否则保留原值
  • ungroup():取消分组,回到普通数据框

方法2:使用data.table包(适合大数据)

如果数据量很大,data.table的效率更高:

library(data.table)

setDT(df)
df_filled <- df[, lapply(.SD, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x)), 
                by = state_abr]

代码说明:

  • setDT(df):将普通数据框转为data.table格式
  • by = state_abr:按州分组
  • lapply(.SD, ...):对每个分组内的所有列(.SD表示Subset of Data)应用函数
  • 函数逻辑和dplyr一致:NA值替换为组内列均值

方法3:基础R实现(无需额外包)

如果不想加载第三方包,可以用基础R的拆分-处理-合并流程:

# 按州拆分数据框
state_groups <- split(df, df$state_abr)

# 对每个分组处理NA值
state_groups_filled <- lapply(state_groups, function(group) {
  # 遍历每个数值列
  for(col in names(group)[sapply(group, is.numeric)]) {
    col_mean <- mean(group[[col]], na.rm = TRUE)
    group[[col]][is.na(group[[col]])] <- col_mean
  }
  return(group)
})

# 合并回一个数据框
df_filled <- do.call(rbind, state_groups_filled)
# 重置行名
rownames(df_filled) <- NULL

代码说明:

  • split(df, df$state_abr):把数据框按州拆分成列表,每个元素是一个州的数据
  • lapply遍历每个州的数据,对数值列计算均值并替换NA
  • do.call(rbind, ...):把处理后的分组数据合并回一个数据框
验证结果

可以用以下代码查看处理后的结果,确认NA已被对应州的均值填充:

# 查看AL州原NA较多的列
df_filled %>% filter(state_abr == "AL") %>% select(county, poverty, no_comp, no_internet)

内容的提问来源于stack exchange,提问作者Jean-Paul Azzopardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:45:31