5

我在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警告以及来自构建的原始 data.frame 的预测m1

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 )

4/20 跟进:

谢谢大家的回答。我知道通过首先使用正确命名的预测器创建一个 data.frame 会更容易。我明白那个。我的问题是,如果建模数据框确实评估为具有变量命名gc.pc$scores[,1]等的数据框,那么为什么上面使用的命名“策略”不能使用predict.lm?换句话说,真的用等等来lm评估它的建模数据框吗?gc.pc$scores[,1]如果是这样,上面的重命名策略不会起作用predict.lm吗?

4

3 回答 3

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]etc 的变量的数据框。当您使用predict()它时,它将在传递给参数的对象中查找具有这些相同名称的newdata变量。

理想情况下,您将创建一个数据对象,其中包含您想要包含在其中的所有变量并具有适当的名称,例如:

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)
于 2012-04-20T07:42:29.930 回答
1

过去我遇到过类似的问题 - 我想我通过给变量名称而不是引用列号来解决它。例如,不要使用 gc.pc[,1],而是将 gc.pc 矩阵转换为数据框并将名称添加到列(“PC1”、“PC2”……等)。然后确保您的 newdata 也使用这些名称(也在数据框中)。

于 2012-04-20T07:17:13.907 回答
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)])
}
于 2015-11-01T04:11:23.913 回答