如何用 NA 替换 R 中 lm 模型的未知因素?

How to replace by NA the unknown factors for lm model in R?

我有一个在某些数据库上训练的 lm 模型,我想预测另一个数据库的一些值。问题是在 'other' 数据库中,有一些训练数据库中没有的因素。我想用 NA 值替换它们,所以在预测时我也会得到一个 NA 值(我知道使用 predictna.action = na.exclude 会做到这一点)。

因为我没有训练数据库,所以我可以像这样从模型中提取已知因素:model$xlevels[1] # contains the first factor values。这是一个列表,如果我想获取因子的名称,我将使用 names(model$xlevels[1])。所以现在我只想获取包含已知因素的行:

knownData <- subset(allData, names(model$xlevels[1]) %in% model$xlevels[1])

但出现以下错误:

Error in model$xlevels : $ operator is invalid for atomic vectors

所以我是这样拆分的:

factorName <- names(model$xlevels[2])
factorValues <- model$xlevels[2]
knownData <- subset(allData, factorName %in% factorValues)

现在我得到一个空 knownData(0 行),即使有很多已知因素。

我走得更深,所以我做到了

allData[factorName] %in% factorValues
[1] FALSE

好像只有一个值,而且是false。 如何提取已知数据?或者更好:How to replace the unknown factors by NAs?


编辑:

我认为问题在于值的解释,因为如果我这样做

allData$clnm %in% factorValues

我弄错了...

我试图将其解释为一个因素

allData$clnm %in% as.factor(factorValues)

但不工作,我收到一个错误:

Error in sort.list(y) : 'x' must be atomic for 'sort.list'
Have you called 'sort' on a list?

为再现性添加代码 好的,只是为了具有可重复性,这是代码:

trnData = read.csv("http://www.bodowinter.com/tutorial/politeness_data.csv")
model <- lm(frequency ~ attitude + scenario, trnData)

tstData <- rbind(c("H1", "H", 2, "pol", 185),
                 c("M1", "M", 1, "pol", 115),
                 c("F1", "F", 3, "ang", 210))
colnames(tstData) <- colnames(allData)
tstData <- as.data.frame(tstData)

假设我们不知道 trnData,我们可以提取训练中使用的因子的值和名称:

factorName <- names(model$xlevels[1])
factorValues <- model$xlevels[1]

您可以使用 ifelse 将值有条件地替换为 NA

newvar = ifelse(oldvar=="new levels",NA,oldvar)

最好post一个可复现的例子,不然都是瞎猜!!看看这个例子,看看能不能解决你的问题。

n=50
set.seed(123)
d=data.frame(o=rnorm(n,10,3),t=1:n,w=rep(c("A","B","C"),length.out=n))
m=10
td=data.frame(o=rnorm(m,10,3),t=(n+1):(m+n),w=c("D","E",rep(c("A","B","C"),length.out=m-2)))

model <- lm(o ~ t * w,data=d)

cbind(td$o,predict(model,newdata=td[,-1])) #Erro here

newlevels=levels(td$w)[!levels(td$w)%in%levels(d$w)]
ntd=td
ntd$w=factor(ifelse(td$w%in%newlevels,NA,td$w),labels=levels(d$w))
cbind(td$o,predict(model,newdata=ntd[,-1]))

        [,1]      [,2]
1  10.759956        NA
2   9.914360        NA
3   9.871389  9.598080
4  14.105807 10.192217
5   9.322687 10.207865
6  14.549412  9.524874
7   5.353742 10.258272
8  11.753841 10.180756
9  10.371563  9.451669
10 10.647825 10.324328

因为 factorValues 是一个列表,所以 %in% 不起作用,并且 as.factor 也返回错误,因为列表已排序(至少是这样似乎)。因此,要按因子转换列表,应调用 unlist 。问题现已解决:

knownData <- subset(allData, allData[,factorName] %in% factorValues)

还有一个问题:factorName 是 class 字符,所以总是从 %in%

返回 1 FALSE