现在,我有一个来自内置数据集iris的组合。到目前为止,我已被引导能够找到这对值的lm()系数。
myPairs <- combn(names(iris[1:4]), 2)
formula <- apply(myPairs, MARGIN=2, FUN=paste, collapse="~")
model <- lapply(formula, function(x) lm(formula=x, data=iris)$coefficients[2])
model
但是,我想进一步使用lm()中的系数来进一步计算。我想做这样的事情:
Coefficient <- lm(formula=x, data=iris)$coefficients[2]
Spread <- myPairs[1] - coefficient*myPairs[2]
library(tseries)
adf.test(Spread)
程序本身很简单,但我无法为数据集中的每个组合找到一种方法。 (作为旁注,adf.test不适用于此类数据,但我只是使用虹膜数据集进行演示)。 我想知道,为这样的程序编写一个循环会更好吗?
答案 0 :(得分:2)
听起来你想编写自己的函数并在myPairs循环中调用它(应用):
yourfun <- function(pair){
fm <- paste(pair, collapse='~')
coef <- lm(formula=fm, data=iris)$coefficients[2]
Spread <- iris[,pair[1]] - coef*iris[,pair[2]]
return(Spread)
}
然后你可以调用这个函数:
model <- apply(myPairs, 2, yourfun)
我认为这是最干净的方式。但我不知道你究竟想做什么,所以我正在为Spread编写例子。请注意,在我的示例中,您会收到警告消息,因为列Species
是一个因素。
答案 1 :(得分:2)
您可以在combn
内完成所有这些操作。
如果您只想对所有组合运行回归,并提取第二个系数
fun <- function(x) coef(lm(paste(x, collapse="~"), data=iris))[2]
combn(names(iris[1:4]), 2, fun)
然后,您可以扩展该功能以计算点差
fun <- function(x) {
est <- coef(lm(paste(x, collapse="~"), data=iris))[2]
spread <- iris[,x[1]] - est*iris[,x[2]]
adf.test(spread)
}
out <- combn(names(iris[1:4]), 2, fun, simplify=FALSE)
out[[1]]
# Augmented Dickey-Fuller Test
#data: spread
#Dickey-Fuller = -3.879, Lag order = 5, p-value = 0.01707
#alternative hypothesis: stationary
将结果与手动运行第一个结果进行比较
est <- coef(lm(Sepal.Length ~ Sepal.Width, data=iris))[2]
spread <- iris[,"Sepal.Length"] - est*iris[,"Sepal.Width"]
adf.test(spread)
# Augmented Dickey-Fuller Test
# data: spread
# Dickey-Fuller = -3.879, Lag order = 5, p-value = 0.01707
# alternative hypothesis: stationary
答案 2 :(得分:1)
一些提示:我不会说出与内置函数同名的内容(model
,formula
会在您的原始版本中出现。
此外,您可以简化您正在执行的paste
- 请参阅下文。
最后,一个更一般的陈述:不要觉得所有事情都需要在某种*apply
中完成。有时简洁和短代码实际上更难理解,并且记住,*apply
函数提供了最好的,边际速度增益,而不是简单的for
循环。 (R
的情况并非总是如此,但现在正是这样。)
# Get pairs
myPairs <- combn(x = names(x = iris[1:4]),m = 2)
# Just directly use paste() here
myFormulas <- paste(myPairs[1,],myPairs[2,],sep = "~")
# Store the models themselves into a list
# This lets you go back to the models later if you need something else
myModels <- lapply(X = myFormulas,FUN = lm,data = iris)
# If you use sapply() and this simple function, you get back a named vector
# This seems like it could be useful to what you want to do
myCoeffs <- sapply(X = myModels,FUN = function (x) {return(x$coefficients[2])})
# Now, you can do this using vectorized operations
iris[myPairs[1,]] - iris[myPairs[2,]] * myCoeffs[myPairs[2,]]
如果我理解正确,我相信上述方法会奏效。请注意,目前输出上的名称将是荒谬的,您需要将它们替换为您自己设计的内容(可能是myFormulas
的值)。