在多元线性回归中动态引用列名(lm())

问题描述 投票:0回答:2

如果这个问题措辞不好,我很抱歉,但是经过几个小时的网络搜索,我有信心说这个问题以前没有得到回答。我将尽力详细描述这个问题所涉及的内容。

数据集摘要:使用的数据是从python代码检索并存储在单个CSV文档中的财务数据(开放,高,低,关闭)。使用lapply,然后读取并存储文档。为了简单起见,我目前关注的是每日百分比变化,或者(关闭/转移(关闭)) - 1。出于这个问题的目的,我从数据中删除了所有NAs以及非完整的代码。

我有一个98列(代码)的数据框(从列表转换),跨越1000行(天)。数据框/矩阵中的值是每天的每个股票代码的每日百分比变化。

目标:我想知道如何通过动态引用列名称,使用所有其他列(lm())在每列上应用~ .公式。

样本数据集:

aapl_pct_chg <- c(.02, .03, .01, -.05, -.01)
tmus_pct_chg <- c(-.01, -.02, .05, .01, -.03)
akam_pct_chg <- c(.1, -.2, .3, -.03, -.07)
intc_pct_chg <- c(.01, .03, .02, .01, .1)
de_pct_chg <- c(-.01, -.05, .05, .1, -.03)

df <- as.data.frame(cbind(aapl_pct_chg, tmus_pct_chg, akam_pct_chg, intc_pct_chg, de_pct_chg))

names(df) <- c("AAPL", "TMUS", "AKAM", "INTC", "DE")

这很简单,可以执行以下操作:

lm_aapl <- lm(AAPL ~ ., data=df)

但我一直无法找到一种方法来动态地引用列名而不会遇到错误。我的意思是,理想情况下,我可以运行一个公式来捕获每列上的lm()模型,使用其他所有列。

有一些已回答的问题得到了帮助(我道歉,我没有组织,并以500种不同的方式尝试过这种方法),但没有一个能解决它。我最接近的是一个符合我想要的公式,但它会在预测AAPL时包含AAPL的值 - 这会导致一个好的模型而不是我想要的。

r apply linear-regression lapply finance
2个回答
1
投票

由于您可以在模型公式中使用.来表示所有剩余变量,因此您可以使用paste轻松地将公式的向量构造为字符串。通常的下一步是使用lapply或类似方法迭代它,在字符串上调用as.formula(未矢量化)然后应用公式。全部一起,

df <- data.frame(AAPL = c(0.02, 0.03, 0.01, -0.05, -0.01), 
                 TMUS = c(-0.01, -0.02, 0.05, 0.01, -0.03), 
                 AKAM = c(0.1, -0.2, 0.3, -0.03, -0.07), 
                 INTC = c(0.01, 0.03, 0.02, 0.01, 0.1), 
                 DE = c(-0.01, -0.05, 0.05, 0.1, -0.03))

models <- lapply(paste(names(df), '~ .'), 
                 function(f){ lm(as.formula(f), data = df) })

models[[1]]
#> 
#> Call:
#> lm(formula = as.formula(f), data = df)
#> 
#> Coefficients:
#> (Intercept)         TMUS         AKAM         INTC           DE  
#>     0.01941      0.52529      0.02116     -0.33372     -0.70687

注意调用不是很漂亮,所以如果你想拼接公式,请使用substituteeval得到的表达式:

models <- lapply(paste(names(df), '~ .'), function(f){
    eval(substitute(lm(frm, data = df), 
                    list(frm = as.formula(f))))
})

models[[2]]
#> 
#> Call:
#> lm(formula = TMUS ~ ., data = df)
#> 
#> Coefficients:
#> (Intercept)         AAPL         AKAM         INTC           DE  
#>    -0.03694      1.90370     -0.04028      0.63530      1.34566

0
投票

您可以创建动态语句并使用eval()parse()来解释它

names(df) <- c("AAPL", "TMUS", "AKAM", "INTC", "DE")
for (n in names(df)) {
    code <- paste0("lm_", n , " <- lm(", n, " ~ ., data=df)")
    eval(parse(text=code))
}
© www.soinside.com 2019 - 2024. All rights reserved.