使用RMarkdown自动化调查摘要

本指南介绍了如何使用RStudio自动使用R和R Markdown进行调查摘要。这对于不改变的文档部分是很好的(例如,“调查显示了实质上的党派偏振”)。动机实际上是双重的:效率(最大化代码的可重用性,最小化复制和粘贴错误)和可重复性(最大化可以重现发现的人和计算机的数量)。

基本设置是编写一个Rmd用作模板的文件,然后编写一个循环遍历每个数据文件的简短R脚本(使用library(knitr))。所述render然后功能会将Rmd到文档或幻灯片(通常在PDF,HTML或docx通过取文件元数据作为)参数

有无数的方法来概括调查R.本指南介绍了一些基础知识,ggplot和questionr,但着眼于整个工作流(文件管理等)。按照这里的说明,您应该能够重现所有四个报告(原则上,更多),尽管只编写代码来清理一个调查。大多数代码都显示在本文档中,但所有代码都可以在pewpoliticaltemplate.Rmd或中找到pew_report_generator.R。所有代码以及输出的文档都可以在这里找到,有关获取数据的详细信息,请参见下文。

软件

RStudio的界面library(rmarkdown)正在迅速发展。强烈建议安装当前版本的RStudio,特别是对于R Markdown代码的预览(此文档是使用RStudio 1.1.83创建的)。(这是我的安装指南,其中包含教程和备忘单的链接。有关更高级的调查数据清理,请单击此处。)

即使你以前编织过Rmd,你的库也可能不够新,无法创建参数化报告。我建议安装pacman,它具有便利功能p_load,可以平滑包安装,装载和维护。p_load如果你在Dropbox上进行合作,我会特别推荐。

install.packages("pacman")

p_load(rmarkdown, knitr, foreign, scales, questionr, tidyverse, update = TRUE)

记住PDF要求LaTeX (安装链接)。相比之下,针织docx或HTML不需要LaTeX。pptx可以在R中创建library(ReporteRs),但这里不讨论。

数据

下载来自皮尤研究四个“政治调查”可以在这里(即一月,三月,八月和十月2016)。你可能还记得,有些政治事件发生在2016年。(这些数据是免费的,只要你花一点时间来开帐户。)

  • 如果需要,解压缩每个zip文件夹。

我的三个文件夹都有直观的名字(Jan16,Mar16和Oct16),但我的一个文件夹里有一个冗长的名字,http___www.people-press.org_files_datasets_Aug16。别担心。

  • 创建一个新文件夹,调用它,比如说automating。

  • 将所有四个数据文件夹移动到automating。

请注意,我与Pew Research没有任何关系(过去或现在)。我只是认为他们做了很棒的工作,并且他们可以相对轻松地开始使用有意义的数据集。

Markdown 模版

在RStudio中,创建一个新的R笔记本并将其保存为刚刚创建pewpoliticaltemplate.Rmd的automating文件夹。该文件可能HTML默认编织; 按住编织按钮将其更改为PDF。根据需要向标题添加字段。下面的示例标题通过解析Date:R代码旁边的表达式自动将今天的日期放在文档上。classoption: landscape可能有助于广泛的表格。您还可以使用多种格式指定包含参考书目的文件,例如BibTex和EndNote (引文详细信息)

接下来添加一个R代码块来pewpoliticaltemplate.Rmd处理格式化等背景内容。虽然只需编织设置工作目录Rmd,但必须设置目录knitr::opts_knit$set(root.dir = '...')以自动执行文档准备。(如果您仍在编辑,setwd则不需要Rmd,但Console建议单独设置工作目录。)

[图片上传失败...(image-37c147-1547913882066)]

右上角的“播放”按钮可以预览代码的输出,非常方便。如果分析的某些部分非常冗长,则只需运行一次,即可让您对图形等进行修补。

  • 现在已经设置了默认设置,您无需担心每个代码块都会抑制警告等。当然,您可以根据需要逐个更改它们。

  • 与R不同,在设置单个代码块的格式选项时(如上所示,在默认启动之前禁止显示警告),您需要输入单词TRUE并FALSE完整填写。

  • 与模板不同,在本文档中,我将默认值设置为echo = TRUE并tidy = TRUE更好地显示R代码。

  • 该设置asis = TRUE对专业格式的表非常有用(如下所示),但不建议用于矩阵和表的原始R输出。要kable默认显示原始数据框,请参见此处

我发现最简单的方法是编写一个完整的工作示例,然后根据需要进行少量更改,以便knitr::render()循环遍历数据集。首先要做的事情。

survey <- read.spss("Jan16/Jan16 public.sav", to.data.frame = TRUE)

可以轻松地将摘要统计信息插入到文本中,如下所示:

[图片上传中...(image-a6b159-1547913649827-0)]

该模板包含具有调查权重的其他示例(较长的计算应在代码块中完成,然后使用该内联样式引用其结果)。

这是我们可能想要的基本情节,它反映了调查权重。facet_grid()用于为每个参与方识别创建类似的图。该图使用稍微不稳定的语法y = (..count..)/sum(..count..)将结果显示为百分比而不是计数。请注意,为简洁起见,省略了一些清理数据的代码(主要是缩短标签),但可以在此处找到。

我发现最简单的方法是编写一个完整的工作示例,然后根据需要进行少量更改,以便knitr::render()循环遍历数据集。首先要做的事情。

survey <- read.spss("Jan16/Jan16 public.sav", to.data.frame = TRUE)

可以轻松地将摘要统计信息插入到文本中,如下所示:


该模板包含具有调查权重的其他示例(较长的计算应在代码块中完成,然后使用该内联样式引用其结果)。

这是我们可能想要的基本情节,它反映了调查权重。facet_grid()用于为每个参与方识别创建类似的图。该图使用稍微不稳定的语法y = (..count..)/sum(..count..)将结果显示为百分比而不是计数。请注意,为简洁起见,省略了一些清理数据的代码(主要是缩短标签),但可以在此处找到。

PA <- ggplot(survey) + theme_minimal()
PA <- PA + geom_bar(aes(q1, y = (..count..)/sum(..count..), weight = weight, 
    fill = q1))
PA <- PA + facet_grid(party.clean ~ .) + theme(strip.text.y = element_text(angle = 45))
PA <- PA + xlab("") + ylab("Percent of Country")
PA <- PA + ggtitle("Presidential Approval: January 2016")
PA <- PA + scale_y_continuous(labels = scales::percent)
PA

以下是加权交叉表的示例。knitr::kable将创建一个专业的表格(当编织时PDF; kable采用学术期刊的风格)。
kable(wtd.table(surveyideo, surveysex, survey$weight)/nrow(survey), digits = 2)

假设我们要显示总统批准,其中第一列提供整体批准,后续列是各种感兴趣因素的交叉表(使用单元格权重)。我写了一个名为Xtabs的便利函数来创建这种格式,这在调查领域很常见。

source("[https](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[://](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[raw](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[.](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[githubusercontent](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[.](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[com](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[/](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[rdrr1990](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[/](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[datascience101](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[/](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[master](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[/](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[automating](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[/](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[Xtabs](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[.](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)[R](https://raw.githubusercontent.com/rdrr1990/datascience101/master/automating/Xtabs.R)")

kable(Xtabs(survey, "q1", c("sex", "race"), weight = "cellweight"))

假设我们想做很多交叉表。语法survey$ideo被广泛用于方便,但survey[["ideo"]]它将更好地为我们服务,因为它允许我们使用变量名称的向量(来自win-vector的细节)。下面,前两个比较调用是相同的,但最后一个不是因为数据框中没有变量“x” survey。

identical(survey$ideo, survey[["ideo"]])
[1] TRUE
x <- "ideo"
identical(survey[[x]], survey[["ideo"]])
[1] TRUE
identical(survey[[x]], survey$x)
[1] FALSE

所以说我们希望所有问题20,21,22交叉的意识形态和党ID的加权交叉表.29。这里有一些代码可以做到这一点。

x <- names(survey)[grep("q2[[:digit:]]", names(survey))]
x
 [1] "q20"  "q21"  "q22a" "q22b" "q22c" "q22d" "q22e" "q22f" "q22g" "q22h"
[11] "q22i" "q25"  "q26"  "q27"  "q28" 
y <- c("ideo", "party")
for (i in x) {
    for (j in y) {
        cat("\nWeighted proportions for", i, "broken down by", j, "\n")
        print(kable(wtd.table(survey[[i]], survey[[j]], survey$weight)/nrow(survey), 
            digits = 2))
        cat("\n")  # break out of table formatting
    }
    cat("\\newpage")
}

几点说明:

  • 此代码仅适用于asis设置(如上所示),该设置允许knitr将输出解释print(kable())为要呈现的内容(而不仅仅是显示用于其他地方的Markdown代码)。

  • 理想情况下,人们会有一个csv或data.frame多个问题,并将其显示为循环切换问题。在这种情况下,调查问卷是在一个docx,所以library(docxtrackr)可能有所帮助。

  • 而不是嵌套循环,人们可能更愿意选择一个问题,循环交叉表的人口统计和意识形态类别,然后插入评论和概述。

  • 外部循环在每次运行时都会生成一个新页面,内部循环使用cat("\newpage")),特定于渲染为PDF。\n需要额外的换行符来打破表格格式并保持代码和文本分开。docx需要一种不同的分页方法。

使用参数调整模版

下一步是添加一个包含所需变量的参数。参数将由下面讨论的R脚本控制。当然,对于由哪个文件控制的内容有很多选择,但通常只需要少量参数。将以下内容添加到标题的末尾pewpoliticaltemplate.Rmd:

这会创建变量paramsspssfile并且paramssurveywave可以从其他R会话外部控制,1并2016分别给出它们的默认值。设置默认值可以让你继续Rmd自己编织(而不是从我们稍后会创建的R脚本中设置默认值...您也可以单击Knit并选择Knit with Parameters指定特定值)。
现在对Rmd模板进行任何更改。例如,在ggplot代码中......

PA <- PA + ggtitle(paste("Presidential Approval:", params$surveywave))

请注意,我们可以获得所有spss文件的列表,如下所示:

dir(pattern = "sav", recursive = TRUE)

[1] "http___[www.people-press.org_files_datasets_Aug16/Aug16](http://www.people-press.org_files_datasets_aug16/Aug16)public.sav"

[2] "Jan16/Jan16 public.sav"                                           

[3] "March16/March16 public.sav"                                       

[4] "Oct16/Oct16 public.sav"

或者在这种情况下

dir(pattern = "16 public.sav", recursive = TRUE)

[1] "http___[www.people-press.org_files_datasets_Aug16/Aug16](http://www.people-press.org_files_datasets_aug16/Aug16)public.sav"

[2] "Jan16/Jan16 public.sav"                                           

[3] "March16/March16 public.sav"                                       

[4] "Oct16/Oct16 public.sav"

如果您或您的协作者添加spss具有相似名称的其他文件,我建议尽可能使模式具体。要使用正则表达式指定更复杂的模式,请参见此处

现在回到编辑pewpoliticaltemplate.Rmd......


使用这些默认设置编织文件以查看其外观; 就是这个部分。

knitr 自动化

现在创建一个新的R脚本; 我的叫pew_report_generator.R。它只是一个简单的循环,它告诉要抓取哪个数据集,以及要传递给的标签Rmd。请注意,标签按字母顺序而不是按时间顺序显示,作为Rmd查找文件的方式的函数。

library(pacman)
p_load(knitr, rmarkdown, sessioninfo)

setwd("/users/mohanty/Desktop/pewpolitical/")

waves <- c("August 2016", "January 2016", "March 2016", "October 2016")

for (i in 1:length(waves)) {
    render("pewpoliticaltemplate.Rmd", params = list(spssfile = i, surveywave = waves[i]), 
        output_file = paste0("Survey Analysis ", waves[i], ".pdf"))
}

session <- session_info()
save(session, file = paste0("session", format(Sys.time(), "%m%d%Y"), ".Rdata"))

而已。当然,在实践中,您可能会在第一次调查中编写一些代码,但这些代码并不适用于所有这些代码。例如,皮尤似乎在最近两次调查中对调查日期的格式不同,这使我做了一些改变。但是,如果数据的格式相当一致,那么一次性投资可以节省大量的时间,使其容易出错,并且容易出错。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章