如何在data.table的指定列中用众数替换NA值
解决方案
问题原因
你遇到的警告是因为zoo::na.aggregate默认使用mean函数填充缺失值,但因子类型无法计算均值。虽然你定义了众数计算函数calc_mode,但参数传递错误——na.aggregate的第二个参数是指定填充用的函数(FUN),你传入的2是无效参数,导致函数仍尝试用均值处理因子列,触发警告。
方案1:修正zoo包的用法
只需要调整na.aggregate的参数传递,直接指定FUN = calc_mode即可:
library(data.table) library(zoo) train_set <- data.table(A = sample( c("BOBO", "BABA"), 100, TRUE), B = sample( c("TOTO", "TATA"), 100, TRUE)) cols <- names(Filter(is.character, train_set)) train_set[, (cols) := lapply(.SD, as.factor), .SDcols = cols] train_set[c(1, 4, 9), A := NA] train_set[c(2, 5, 10), B := NA] calc_mode <- function(x){ distinct_values <- unique(x) distinct_tabulate <- tabulate(match(x, distinct_values)) distinct_values[which.max(distinct_tabulate)] } cols <- names(Filter(is.factor, train_set)) # 修正参数,直接指定FUN为calc_mode train_set[ , (cols) := lapply(.SD, na.aggregate, FUN = calc_mode), .SDcols = cols]
方案2:不使用zoo包,纯data.table实现
如果你不想依赖zoo包,可以直接遍历因子列,用calc_mode计算每列的众数,然后替换NA值:
library(data.table) train_set <- data.table(A = sample( c("BOBO", "BABA"), 100, TRUE), B = sample( c("TOTO", "TATA"), 100, TRUE)) cols <- names(Filter(is.character, train_set)) train_set[, (cols) := lapply(.SD, as.factor), .SDcols = cols] train_set[c(1, 4, 9), A := NA] train_set[c(2, 5, 10), B := NA] calc_mode <- function(x){ distinct_values <- unique(x) distinct_tabulate <- tabulate(match(x, distinct_values)) distinct_values[which.max(distinct_tabulate)] } cols <- names(Filter(is.factor, train_set)) # 遍历因子列,用众数填充NA train_set[, (cols) := lapply(.SD, function(x) { mode_val <- calc_mode(x[!is.na(x)]) x[is.na(x)] <- mode_val x }), .SDcols = cols]
补充说明
- 你的
calc_mode函数可以正常计算因子的众数,无需修改 - 两种方案都能实现用列的众数填充因子类型的缺失值,不会再触发警告
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

