如何用 NA 替换 R 中 lm 模型的未知因素?
How to replace by NA the unknown factors for lm model in R?
我有一个在某些数据库上训练的 lm 模型,我想预测另一个数据库的一些值。问题是在 'other' 数据库中,有一些训练数据库中没有的因素。我想用 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
好像只有一个值,而且是false。
如何提取已知数据?或者更好:How to replace the unknown factors by 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]
您可以使用 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
我有一个在某些数据库上训练的 lm 模型,我想预测另一个数据库的一些值。问题是在 'other' 数据库中,有一些训练数据库中没有的因素。我想用 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
好像只有一个值,而且是false。
如何提取已知数据?或者更好:How to replace the unknown factors by 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]
您可以使用 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%
FALSE