4

我有一个包含 498 个各种数字、逻辑、日期等变量的数据集,我将其作为 R 中的数据框,其中行用于观察,列用于变量。这些变量的某个子集我想用该变量的平均值替换它们的缺失值。

我为平均插补编写了这个非常简单的函数:

impute.mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))

如果我应用到单个变量,比如 dataset$variableA,这将非常有效:

dataset$variableA <- impute.mean(dataset$variableA)

这样做给了我对一个变量的确切要求,但是因为我有相当大的变量子集需要为此执行此操作,所以我不想通过遍历每个需要插补的变量来手动执行此操作。

我的第一直觉是使用 R 中的一个应用函数来有效地做到这一点,但我似乎不明白如何准确地做到这一点。

粗略的第一次尝试是使用标准 apply:

newdataset <- apply(dataset, 2, impute.mean)

这显然有点粗略,因为它试图将函数应用于所有列,包括非数字变量,但它似乎是一个合理的起点,即使它可能会产生许多警告。唉,这种方法不起作用,我的所有变量都保持不变。

我还对 lapply、mapply、ddply 进行了一些实验,但到目前为止没有任何成功。

理想情况下,我希望能够做这样的事情:

relevantVariables <- c("variableA1", "variableA2", ..., "variableA293")
newdataset <- magical.apply(dataset, relevantVariables, impute.mean)

是否有一些以这种方式工作的应用功能?

或者,是否有其他有效的方法来解决这个问题?

4

2 回答 2

1

您可以使用 data.table 包有效地做到这一点:

SetNAsToMean <- function(dt, vars) {                                                                                                                             
  # Sets NA values of columns to the column means                                                                                                                
  #                                                                                                                                                              
  # Args:                                                                                                                                                        
  #   dt: data.table object to work with                                                                                                                         
  #   vars: vector of column names to replace NAs                                                                                                                
  #                                                                                                                                                              
  # Returns:                                                                                                                                                     
  #   Nothing. Alters data.table in place.                                                                                                                       
  #                                                                                                                                                              
  # Example:                                                                                                                                                     
  #   dt <- data.table(num1 = c(1, NA, 3),                                                                                                                       
  #                    num2 = c(NA, NA, 4),                                                                                                                      
  #                    char1 = rep("a", 3))                                                                                                                      
  #   SetNAsToMean(dt, c("num1", "num2"))                                                                                                                        
  #   # Alternatively, set all numeric columns                                                                                                                    
  #   numerics <- which(lapply(dt, class) == "numeric")                                                                                                           
  #   SetNAsToMean(dt, numerics)
  require(data.table)
  for (var in vars) {                                                                                                                                            
    set(dt, which(is.na(dt[[var]])), var, mean(dt[[var]], na.rm=T))                                                                                              
  }                                                                                                                                                              
}           
于 2014-03-29T19:51:36.140 回答
0

那会让你满意吗?

for (j in 1:length(dataset[1,]))
    {

        if (is.numeric(dataset[,j]))
        {
            for(k in 1:length(dataset[,1]))
            {
                if(is.na(dataset[k,j]))
                {
                    dataset[k,j] <- mean(dataset[,j],na.rm=T)
                }
            }
        }
    }
于 2013-06-25T13:10:33.147 回答