R中的stargazer package非常适合将多个回归模型显示为并排列 - 许多社会科学学科的标准样式。但是,该程序包与knitr + pandoc不能很好地兼容,因为它可以生成HTML或TeX输出,但不能生成Markdown。
作为一个解决方案,我创建了一个可以生成类似于用stargazer创建的表的函数,但是将输出保存为一个简单的数据框,然后我可以使用像kable
这样的pacak来渲染和pander
在针织文件中。使用broom::tidy
等函数执行此操作非常简单。
c("wt", "qsec", "hp", "cyl", "gear", "carb", "drat")
。所有系数的顺序主要基于第一模型中的系数(wt
,qsec
,cyl
,gear
,carb
)。当第二个模型作为新列附加时,hp
行将在qsec
之后和cyl
之前插入。
lm0 <- lm(hp ~ wt + qsec + cyl + gear + carb, mtcars)
lm1 <- lm(qsec ~ hp + cyl + gear + carb, mtcars)
lm2 <- lm(qsec ~ wt + hp + gear + drat, mtcars)
stargazer(lm0, lm1, lm2, type="text")
====================================================
(1) (2) (3)
----------------------------------------------------
wt 16.879 0.827**
(12.113) (0.383)
qsec -8.124
(6.109)
hp -0.005 -0.026***
(0.007) (0.004)
cyl 18.210** -0.811***
(8.785) (0.280)
gear 13.342 -1.597*** -0.232
(15.115) (0.441) (0.439)
carb 9.277 0.098
(6.345) (0.222)
drat 0.099
(0.636)
Constant 49.424 29.181*** 19.530***
(171.876) (2.398) (2.766)
====================================================
Note: *p<0.1; **p<0.05; ***p<0.01
最后,我希望生成系数名称的字符向量,然后我可以使用dplyr::arrange()
来正确排序多个模型系数的数据帧。
排序似乎遵循这种伪算法:
list_1
)element_1
的{{1}}与list_2
的{{1}}不匹配,请检查element_1
的下一个元素,直到匹配为止,然后插入比赛前list_1
之后list_1
的{{1}}如果与element_2
list_2
element_1
,依此类推然而,编写简单的R代码来生成此顺序已经证明比我想象的更难。简单地连接一个向量中的所有系数名称然后只保留唯一值并不能产生正确的顺序,因为新的变量(如list_1
)只是添加到现有变量名的末尾而不是插入在中间:
list_3
此外,似乎实现这样的事情的唯一方法是使用大量的循环,这感觉非常低效。
那么,最后,我如何按照模型列表中的出现顺序对系数名称的字符向量进行排序或重新排序,优先考虑列表中第一个模型的顺序?也就是说,最终这是我想得到的字符向量:hp
更新:library(tidyverse)
names1 <- names(lm0$coefficients) %>% discard(~ .x == "(Intercept)")
names2 <- names(lm1$coefficients) %>% discard(~ .x == "(Intercept)")
names3 <- names(lm2$coefficients) %>% discard(~ .x == "(Intercept)")
# New variables just appended
unique(c(names1, names2, names3))
# [1] "wt" "qsec" "cyl" "gear" "carb" "hp" "drat"
是实际返回数据框(而不仅仅是文字)的neat alternative to stargazer,但它不会在现有订单中插入新系数,而是将它们附加到列表(最后有c("wt", "qsec", "hp", "cyl", "gear", "carb", "drat")
和memisc::mtable(lm0, lm1, lm2)
)。它似乎只是连接所有系数名称并使用它们的唯一值。
hp
答案 0 :(得分:1)
回答OP的Q
那么,最后,我如何按照模型列表中的出现顺序对系数名称的字符向量进行排序或重新排序,优先考虑列表中第一个模型的顺序?
这是一个单行程,适用于任意数量的模型:
unique(names(unlist(lapply(list(lm0, lm1, lm2), coef))))[-1]
#[1] "wt" "qsec" "cyl" "gear" "carb" "hp" "drat"
请注意,代码隐含假设第一个模型始终具有"(Intercept)"
作为第一个系数,通过负索引[-1]
从结果向量中删除。
如果无法保证这一点,那么使用
会更安全setdiff(unique(names(unlist(lapply(list(lm0, lm1, lm2), coef)))), "(Intercept)")
如果有任何且无论其位置如何,都会从结果向量中删除"(Intercept)"
。其余的系数名称将保持其顺序:
#[1] "wt" "qsec" "cyl" "gear" "carb" "hp" "drat"
修改强>
不太明确哪个逻辑stargazer
已经实现了对系数进行排序。但是,根据帮助页面,stargazer
也会无形地返回与字符向量相同的输出。此外,table.layout
参数可用于仅返回系数部分。这可用于以与stargazer
:
sgt <- capture.output(stargazer::stargazer(lm0, lm1, lm2, type="text", table.layout = "t"))
setdiff(stringr::str_extract(sgt, "^\\w*"), c("", "Constant"))
#[1] "wt" "qsec" "hp" "cyl" "gear" "carb" "drat"
当stargazer
使用cat()
输出时,capture.output()
会使控制台输出保持干净(感谢@Andrew建议这样做。)
str_extract()
中的正则表达式会返回第一个&#34;字&#34;在每个字符串的开头。使用setdiff()
再次清除结果向量。