我有一个在某个数据库上训练的lm模型,我想预测另一个数据库的某些值。问题是,在其他'数据库,有些因素不在培训数据库中。我想用NA值替换那些,所以在预测时我也会得到一个NA值(我知道使用predict
和na.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]
答案 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
%in%