我在不使用lm
参数的情况下构建了data=
模型:
m1 <- lm( mdldvlp.trim$y ~ gc.pc$scores[,1] + gc.pc$scores[,2] + gc.pc$scores[,3] +
gc.pc$scores[,4] + gc.pc$scores[,5] + gc.pc$scores[,6] + predict(gc.tA))
现在,我想使用m1
预测newdata
,因此请将我的新data.frame命名为与上面lm()
调用中使用的变量相匹配。
将newComps
作为我的新gc.pc
(与gc.tA
预测一样,使用新的data.frame进行预测,没有任何问题),我试过了
newD <- data.frame( newComps[1:100,1:6] ,
predict(gc.tA , newdata = mdldvlp[1:100,predKept]))
names(newD) <- names(m1$coefficients)[-1]
names(newD) <- names(m1$model)[-1]
names(newD) <- c( "gc.pc$scores[, 1]" , "gc.pc$scores[, 2]" , "gc.pc$scores[, 3]" ,
"gc.pc$scores[, 4]" , "gc.pc$scores[, 5]" , "gc.pc$scores[, 6]" ,
"predict(gc.tA)" )
names(newD) <- c( "gc.pc$scores[,1]" , "gc.pc$scores[,2]" , "gc.pc$scores[,3]" ,
"gc.pc$scores[,4]" , "gc.pc$scores[,5]" , "gc.pc$scores[,6]" ,
"predict(gc.tA)" )
不幸的是,predict.lm
不接受上面的命名策略,并返回可怕的newdata
警告以及构建m1
的原始data.frame中的预测:
Warning message:
'newdata' had 100 rows but variable(s) found have 1414 rows
如何命名newD
列以使predict
调用工作?感谢。
以下代码重新创建了问题:
require(rpart)
set.seed(123)
X <- matrix(runif(200) , 20 , 10)
gc.pc <- princomp(X)
y <- runif(20)
mdldvlp.trim <- data.frame(y,X)
names(mdldvlp.trim) <- c("y",paste("x",1:10,sep=""))
predKept <- paste("x",1:10,sep="")
gc.tA <- rpart( y ~ . , data = mdldvlp.trim)
m1 <- lm( mdldvlp.trim$y ~ gc.pc$scores[,1] + gc.pc$scores[,2] + gc.pc$scores[,3] +
gc.pc$scores[,4] + gc.pc$scores[,5] + gc.pc$scores[,6] + predict(gc.tA))
mdldvlp <- data.frame(matrix(runif(2000) , 200 , 10))
names(mdldvlp) <- predKept
newComps <- predict( gc.pc , newdata=mdldvlp )
newD <- data.frame( newComps[1:100,1:6] ,
predict(gc.tA , newdata = mdldvlp[1:100,predKept]))
# enter newD naming strategy here
predict( m1 , newdata=newD )
感谢大家的回答。我理解通过首先使用正确命名的预测变量创建data.frame会更容易。我明白那个。我的问题是,如果建模数据框确实评估为具有名为gc.pc$scores[,1]
等变量的数据框,那么为什么上面使用的命名“策略”不能与predict.lm
一起使用?换句话说,lm
是否真的用gc.pc$scores[,1]
评估其建模数据框架等等?如果确实如此,那么上面的重命名策略不会在predict.lm
?
答案 0 :(得分:8)
您正在滥用公式表示法,这就是导致您出现问题的原因。基本上你的公式:
m1 <- lm( mdldvlp.trim$y ~ gc.pc$scores[,1] + gc.pc$scores[,2] +
gc.pc$scores[,3] + gc.pc$scores[,4] +
gc.pc$scores[,5] + gc.pc$scores[,6] +
predict(gc.tA))
将使用名为gc.pc$scores[,1]
等变量评估数据框。当您使用predict()
时,它将在传递给newdata
参数的对象中查找具有相同名称的变量。< / p>
理想情况下,您可以使用适当的名称创建一个包含所有要包含的变量的数据对象,例如:
fitData <- data.frame(mdldvlp.trim$y, gc.pc$scores[, 1:6], predict(gc.tA))
names(fitData) <- c("trimY", paste("scores", 1:6, sep = ""), "preds")
然后通过以下方式拟合模型:
m1 <- lm(trimY ~ ., data = fitData)
通过提供与用于拟合模型的名称相同的数据框,可以从模型中进行新的预测。因此,请使用newD
:
newD <- data.frame(newComps[1:100,1:6] ,
predict(gc.tA , newdata = mdldvlp[1:100,predKept]))
names(newD) <- c(paste("scores", 1:6, sep = ""), "preds")
然后predict()
predict(m1 , newdata=newD)
require(rpart)
set.seed(123)
X <- matrix(runif(200) , 20 , 10)
gc.pc <- princomp(X)
y <- runif(20)
mdldvlp.trim <- data.frame(y,X)
names(mdldvlp.trim) <- c("y",paste("x",1:10,sep=""))
predKept <- paste("x",1:10,sep="")
gc.tA <- rpart( y ~ . , data = mdldvlp.trim)
fitData <- data.frame(mdldvlp.trim$y, gc.pc$scores[, 1:6], predict(gc.tA))
names(fitData) <- c("trimY", paste("scores", 1:6, sep = ""), "preds")
m1 <- lm(trimY ~ ., data = fitData)
mdldvlp <- data.frame(matrix(runif(2000) , 200 , 10))
names(mdldvlp) <- predKept
newComps <- predict( gc.pc , newdata=mdldvlp )
newD <- data.frame(newComps[1:100,1:6] ,
predict(gc.tA , newdata = mdldvlp[1:100,predKept]))
names(newD) <- c(paste("scores", 1:6, sep = ""), "preds")
predict(m1 , newdata=newD)
答案 1 :(得分:1)
我过去曾遇到过类似的问题 - 我认为我通过提供变量名而不是引用列号来解决它。例如不要使用gc.pc [,1],而是将gc.pc矩阵转换为数据帧并将名称添加到列(“PC1”,“PC2”,...等)。然后确保您的newdata也使用这些名称(也在数据框中)。
答案 2 :(得分:1)
我有类似的问题。如果我的数据框有三个或更多变量(一个结果和两个或多个预测变量),我按列号引用列时没有问题。但是,当我的数据框只有两个变量(一个结果,一个预测变量)时,R给了我很多错误,包括'newdata' had 1 row but variables found have xx rows
在框中的Marc建议之后,我写了一个特例,其中数据框只有两个变量,并分配了变量名。这解决了我的问题。
为了解决这个警告,我改写了:
lr <- lm(train[ , ncol(train)] ~ ., data = train[ , -ncol(train)])
为:
if(ncol(train) == 2) {
colnames(train) <- c('var1','var2')
colnames(test) <- c('var1','var2')
lr <- lm(var2 ~ var1, data = train)
} else if (ncol(train) > 2) {
lr <- lm(train[ , ncol(train)] ~ ., data = train[ , -ncol(train)])
}