1 加载包

  1. library(dplyr)
  2. (starwars <- starwars[, 1:10]) # starwars后 3 列数据位列表,为便于操作,仅选取前 10 列

image.png

2 缺失值所在行

  1. # 显示缺失值总数
  2. starwars %>% is.na() %>% sum()
  3. # 显示缺失值占比
  4. starwars %>% is.na() %>% mean()
  5. # 显示含缺失值的行总数
  6. sum(!complete.cases(starwars))
  7. # 显示含缺失值的行占比
  8. mean(!complete.cases(starwars))
  9. # 识别含缺失值的行号
  10. which(is.na(starwars))
  11. # 筛选出含缺失值的行
  12. starwars[!complete.cases(starwars),]
  13. # 根据含缺失值的某列筛选对应含缺失值的行
  14. starwars %>% filter(is.na(gender))

3 缺失值所在列

3.1 自定义函数

  1. na.test <- function(df){
  2. i <- 1:ncol(df)
  3. df[i[
  4. sapply(i, function(x){sum(is.na(df[x])) > 0})
  5. ]] %>% colnames()
  6. }
  7. starwars %>% na.test

image.png

3.2 inspect包

  1. library(inspectdf)
  2. starwars %>% inspect_na() %>% filter(cnt != 0)
  3. starwars %>% inspect_na() %>% filter(cnt != 0) %>% show_plot

image.png

image.png

4 应用案例

新建一个贷款合同报表。

  1. contract <- tibble(
  2. 姓名 = c('张三', '李四', '王五'),
  3. 年龄 = c(41, NA, 35),
  4. 学历 = c(NA, '本科', '硕士'),
  5. 省份 = c('湖北省', '江苏省', '新疆维吾尔族自治区'),
  6. 日期 = c('20190101', '20190223', '20190518'),
  7. 首付比例 = c(0.3, NA, 0.4),
  8. 期限 = c(12.00, 24.00, 36.00),
  9. 贷款金额 = c(50000, 60000, 70000),
  10. 车型 = c('Q3', NA, 'Q7'),
  11. 合同编号 = c('N1', 'N2', 'N3')
  12. )
  13. contract %>% View()

image.png
利用自定义的na.test函数查找含缺失值的列字段名。

  1. contract %>% na.test

image.png

发现年龄、学历、首付、车型 4 个字段中存在缺失值。

  1. # 年龄缺失值以平均年龄替换
  2. contract$年龄 %<>% replace_na(mean(ct$年龄, na.rm = TRUE))
  3. # 学历缺失值以“其他”替换
  4. ct$学历 %<>% replace_na('其他')
  5. # “0”首付产品比例缺失,替换为 0
  6. contract$首付比例 %<>% replace_na(0)
  7. # 查询原始表信息,发现合同编号 N2 对应的车型为 Q5
  8. contract %>% filter(is.na(车型)) %>% select(合同编号)
  9. # 将合同编号为N2的合同对应的缺失车型重编码为 Q5
  10. contract$车型[ct$合同编号 == 'N2'] <- 'Q5'