如何用NA取代R中lm模型的未知因素?

时间:2015-07-03 10:29:35

标签: r lm

我有一个在某个数据库上训练的lm模型,我想预测另一个数据库的某些值。问题是,在其他'数据库,有些因素不在培训数据库中。我想用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

似乎只有一个值而且它是错误的。 如何提取已知数据?或者更好:如何用NA s替换未知因素?

修改

我认为问题在于对价值的解释,因为如果我做了

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]

3 个答案:

答案 0 :(得分:2)

最好发布一个可重复的例子,否则我们猜!看看这个例子,看看是否解决了你的问题。

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

答案 1 :(得分:1)

您可以使用ifelse以NA

有条件地替换值
newvar = ifelse(oldvar=="new levels",NA,oldvar)

答案 2 :(得分:1)

由于factorValues是一个列表,%in%无法正常工作,as.factor也返回错误,因为列表已经排序(看起来很像) 。因此,要在因子中转换列表,应调用unlist。问题现在解决了:

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

还有另一个问题:factorName属于班级角色,因此FALSE

总是返回1 %in%