我目前正在尝试在包含一些缺失(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”),没有使用这个参数.