在R中定制na.action

我目前正在尝试在包含一些缺失(NA)值的数据集上构建LDA模型.例如,我想对NA值的均值进行估算.根据我的理解,我可以在lda中设置na.action = na.omit并预测在构建模型时将删除观察值的函数,并在进行预测时强制返回NA.

my.dat <- as.data.frame(cbind(
    c(0, 1, 0, 1, 1, 0),
    c(5, 8, 9, 1, -1, NA),
    c(-2.4, -4.0, -4.4, -0.5, 0.7, -0.3)
))
mod <- lda(my.dat[,-1], my.dat[,1], na.action=na.omit)
predict(mod, my.dat[,-1], na.action=na.omit)

但我现在想要估算出我有NA值的方法.所以,我可以定义自己的na.impute函数.但是,我无法理解传递给这个函数的内容,以及我需要返回的内容.

na.impute <- function (object) {
    print(object)
    object
}

这给了我输出:

[1] g x
<0 rows> (or 0-length row.names)

这对我来说没什么意义.我在文档中找不到任何指导.具体到底是什么,以及如何操纵它以覆盖NA值?

最佳答案 以下是如何找出对象的第一种方法:

na.impute <- function (object) {
  browser()
  print(object)
  object
}

lda(my.dat[,-1], my.dat[,1], na.action=na.impute)
# Called from: na.action(structure(list(g = grouping, x = x), class = "data.frame"))
Browse[1]> str(object)
# 'data.frame': 0 obs. of  2 variables:
#  $g: num  0 1 0 1 1 0
#  $x: matrix [1:6, 1:2] 5 8 9 1 -1 NA -2.4 -4 -4.4 -0.5 ...
#   ..- attr(*, "dimnames")=List of 2
#   .. ..$: NULL
#   .. ..$: chr  "V2" "V3"
Browse[1]> object$g
# [1] 0 1 0 1 1 0
Browse[1]> object$x
#      V2   V3
# [1,]  5 -2.4
# [2,]  8 -4.0
# [3,]  9 -4.4
# [4,]  1 -0.5
# [5,] -1  0.7
# [6,] NA -0.3
# attr(,"class")
# [1] "matrix"

所以它确实是一个不寻常的对象:结构(list(g = grouping,x = x),class =“data.frame”).另一种看到这个的方法,让我们检查函数lda:

lda
# function (x, ...) 
# UseMethod("lda")
# <bytecode: 0x0e3583fc>
# <environment: namespace:MASS>
methods(lda)
# [1] lda.collapsed.gibbs.sampler lda.data.frame*             lda.default*               
# [4] lda.formula*                lda.matrix*                
# 
#    Non-visible functions are asterisked

在这种情况下,我们对lda.data.frame感兴趣.由于它是带星号的,我们必须使用MASS ::: lda.data.frame或getAnywhere(“lda.data.frame”)来查看源代码:

function (x, ...) 
{
    res <- lda(structure(data.matrix(x), class = "matrix"), ...)
    cl <- match.call()
    cl[[1L]] <- as.name("lda")
    res$call <- cl
    res
}
<bytecode: 0x067c3248>
<environment: namespace:MASS>

现在我们可以看到需要lda.matrix,所以再次使用以下两个函数之一:

function (x, grouping, ..., subset, na.action) 
{
    if (!missing(subset)) {
        x <- x[subset, , drop = FALSE]
        grouping <- grouping[subset]
    }
    if (!missing(na.action)) {
        dfr <- na.action(structure(list(g = grouping, x = x), 
            class = "data.frame"))
        grouping <- dfr$g
        x <- dfr$x
    }
    res <- lda.default(x, grouping, ...)
    cl <- match.call()
    cl[[1L]] <- as.name("lda")
    res$call <- cl
    res
}
<bytecode: 0x067bf7b8>
<environment: namespace:MASS>

最后,我们在这里找到了na.action的调用,这是我们所期望的.现在这是一个用列方式替换NA值的函数:

na.impute <- function (object) {
  temp <- object$x
  k <- which(is.na(temp), arr.ind = TRUE)
  temp[k] <- colMeans(temp, na.rm = TRUE)[k[, 2]]
  structure(list(g = object$g, x = as.matrix(temp)), class = "data.frame")
}
lda(my.dat[,-1], my.dat[,1], na.action=na.impute)
# Call:
# lda(my.dat[, -1], my.dat[, 1], na.action = na.impute)
#
# Prior probabilities of groups:
#   0   1 
# 0.5 0.5 
#
# Group means:
#         V2        V3
# 0 6.133333 -2.366667
# 1 2.666667 -1.266667
#
# Coefficients of linear discriminants:
#           LD1
# V2 -0.8155124
# V3 -1.1614265

现在考虑预测和na.action它是不可用的选项:参见getAnywhere(“predict.lda”),没有使用这个参数.

点赞