如何使用公式可靠地使用R中的矩阵(多变量)响应?

如何使用公式可靠地使用R中的矩阵(多变量)响应?,r,machine-learning,predict,multivalue,R,Machine Learning,Predict,Multivalue,我试图在R中使用多变量响应,遇到了该死的公式,并且有各种各样的意外行为,主要是在函数和包中使用它们时。这个问题有两个方面 我可以输入一个多变量响应,并能够使用该模型进行事后预测 此MVE使用rpart包作为示例。这里的y是一个两列矩阵(响应),我想使用x预测y,即x中的每列(此MVE中的两列)。请注意,方法本身和y中的每一列的意思是无关的,这只是一个重现问题的MVE: library(rpart) set.seed(1) y <- rpois(10, lambda = 1.25) y &

我试图在
R
中使用多变量响应,遇到了该死的公式,并且有各种各样的意外行为,主要是在函数和包中使用它们时。这个问题有两个方面

我可以输入一个多变量响应,并能够使用该模型进行事后预测

此MVE使用
rpart
包作为示例。这里的
y
是一个两列矩阵(响应),我想使用
x
预测
y
,即
x
中的每列(此MVE中的两列)。请注意,
方法
本身和
y
中的每一列的意思是无关的,这只是一个重现问题的MVE:

library(rpart)

set.seed(1)
y <- rpois(10, lambda = 1.25)
y <- cbind(c(1,4,10,11,12, 14,16,17,20, 21), y)
print(y)
x <- matrix(1:20, ncol = 2) # just two dummy predictors
print(x)

mymodel <- rpart(y ~ x, method = "poisson", minbucket = 1)

newx <- matrix(11:20, ncol = 2) # just some dummy test predictors, note that we have less rows
predict(mymodel, newdata = data.frame(newx))
# output:
        1          2          3          4          5          6          7          8          
 9         10 
 0.12500000 0.12500000 0.12500000 0.20000000 0.04761905 0.17948718 0.17948718 0.11538462 
 0.04000000 0.04000000 
 Warning message:
 'newdata' had 5 rows but variables found have 10 rows 
库(rpart)
种子(1)

y我没有使用过
rpart:predict
,但是根据文档,对于这个函数,您需要一个新的数据集,该数据集的变量与原始数据集相同

因此,您应该使用正确的列名启动newx:

newx = matrix(11:20, ncol = 2,dimnames=list(NULL,c("x1","x2")))

现在,列被标记为
x1
x2
,正如模型和预测中的变量知道如何处理这些列一样。

一般来说,R中的公式适用于数据帧
rpart
适用于矩阵,虽然数据帧可以保存矩阵,但它们往往会转换为单独的列。为了避免这种情况,请将矩阵包装在
I()
中:

#与开始时的代码相同…然后:
预测(mymodel,newdata=data.frame(x=I(newx)))
#>    1    2    3    4    5 
#> 0.04 0.04 0.04 0.04 0.04
在问题的第二部分中,您正在
mywrapper
函数中创建一个公式,因此如果
newdata
dataframe中不包含变量,它将在其中查找变量。R中的“环境”类似于其他语言中的“堆栈框架”;主要区别在于,环境只有一个父对象,如果在原始环境中找不到该对象,则搜索将继续进行

一般来说,父对象不是调用者的框架,而是创建环境的框架,或者是特别列出的父对象

因此,如果对
mywrapper
返回的值运行
predict
,会发生什么情况?它会查看公式以找到它需要的变量。预测只需要右侧的变量,因此这就是
x
。如果您在
newdata
参数中为
predict
提供
x
,一切都会很好,并像以前一样进行,但如果不提供,情况就不同了

由于在
newdata
中找不到
x
,因此它会转到公式的环境中。这是
mywrapper
的计算框架,它将在那里看到
x
,因为它是该函数的一个参数

如果它寻找的是
z
,它就不会在那里找到它。下一个要查看的地方是父环境,它是创建
mywrapper
时生效的环境,即全局环境。如果没有
z
,它将通过
search()
列出的环境链进行搜索,这些环境通常是包导出。
search()
列表链接在一起,因此每个条目都是前面条目的父条目


我希望这不是太多信息….

如何将其输入到
predict()
?使用
data.frame(newx)
不起作用。至少错误消息有变化吗?使用'newx-Ah,对。训练模型预测给定另一个矩阵的矩阵。你不能把它放在数据框里。如上所述,我自己不使用rpart库。我不知道在这种情况下如何预测。这很有效!而且肯定没有太多的信息,非常感谢。我仍然担心那些“一般来说”,尽管在数据帧中工作良好的公式的例外通常是程序员的错误。由于包作者并不总是专家,有时他们会弄错。rpart的作者知道他们在做什么,所以这不是问题。“parent!=caller”的例外情况通常是父函数显式设置为调用者,但嵌套函数也会发生这种情况:f在本地创建g,然后调用它。
newx = matrix(11:20, ncol = 2,dimnames=list(NULL,c("x1","x2")))