从单个数据库在 R markdown 中创建个人(按行/每个参与者)pdf 报告

Create individual (row-wise / per participant) pdf report in R markdown from a single database

我正在参与一项由 Qualtrics 主持的长期(280 个问题)调查。

作为我工作流程的一部分,我使用 RqualtRics 包直接从 qualtrics 下载数据:

df<-fetch_survey("SV_xxxxxxxx", time_zone = "Europe/Berlin", force_request = T,
                 start_date = "2021-11-01", convert = F, label = T, include_display_order = F)

结果我得到一个 tbl_df 看起来类似于:

df<-structure(list(StartDate = structure(c(1636487307, 1636487369
), class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin", label = c(StartDate = "Start Date")), 
    EndDate = structure(c(1636487364, 1636487424), class = c("POSIXct", 
    "POSIXt"), tzone = "Europe/Berlin", label = c(EndDate = "End Date")), 
    Status = structure(c("IP Address", "IP Address"), label = c(Status = "Response Type")), 
    IPAddress = structure(c("213.134.172.108", "213.134.172.108"
    ), label = c(IPAddress = "IP Address")), Progress = structure(c(100, 
    100), label = c(Progress = "Progress")), `Duration (in seconds)` = structure(c(57, 
    55), label = c(`Duration (in seconds)` = "Duration (in seconds)")), 
    Finished = structure(c(TRUE, TRUE), label = c(Finished = "Finished")), 
    RecordedDate = structure(c(1636487364, 1636487424), class = c("POSIXct", 
    "POSIXt"), tzone = "Europe/Berlin", label = c(RecordedDate = "Recorded Date")), 
    ResponseId = structure(c("R_29nRhq8tofKc2Us", "R_2uOJfVuxexKnO0J"
    ), label = c(ResponseId = "Response ID")), RecipientLastName = structure(c(NA, 
    NA), label = c(RecipientLastName = "Recipient Last Name")), 
    RecipientFirstName = structure(c(NA, NA), label = c(RecipientFirstName = "Recipient First Name")), 
    RecipientEmail = structure(c(NA, NA), label = c(RecipientEmail = "Recipient Email")), 
    ExternalReference = structure(c(NA, NA), label = c(ExternalReference = "External Data Reference")), 
    LocationLatitude = structure(c(52.2483978271484, 52.2483978271484
    ), label = c(LocationLatitude = "Location Latitude")), LocationLongitude = structure(c(21.0025939941406, 
    21.0025939941406), label = c(LocationLongitude = "Location Longitude")), 
    DistributionChannel = structure(c("anonymous", "anonymous"
    ), label = c(DistributionChannel = "Distribution Channel")), 
    UserLanguage = structure(c("EN", "EN"), label = c(UserLanguage = "User Language")), 
    name1 = structure(c("John", "Mary"), label = c(name1 = "First name")), 
    name2 = structure(c("Doe", "Jane"), label = c(name2 = "Birth Name")), 
    yob = structure(c(1982, 1964), label = c(yob = "Year of birth")), 
    mail = structure(c("mail@gmail.com", "mj@green.com"), label = c(mail = "e-mail:")), 
    Q5_1 = structure(c("Strongly disagree", "Strongly agree"), label = c(Q5_1 = "Some scales - question1")), 
    Q5_2 = structure(c("Somewhat disagree", "Strongly agree"), label = c(Q5_2 = "Some scales - question2")), 
    Q5_3 = structure(c("Neither agree nor disagree", "Somewhat agree"
    ), label = c(Q5_3 = "Some scales - question3")), q1 = structure(c("Yes", 
    "No"), label = c(q1 = "Example of a conditional item, where the YES answer leads to an other question;")), 
    q2 = structure(c("No", NA), label = c(q2 = "So... you clicked yes, right?")), 
    `pets#1_1_1` = structure(c("Dizzie", "no pet"), label = c(`pets#1_1_1` = "Click to write the question text - Pet - Pet 1 - name")), 
    `pets#1_2_1` = structure(c("Jumbo", NA), label = c(`pets#1_2_1` = "Click to write the question text - Pet - Pet 2 - name")), 
    `pets#1_3_1` = structure(c(NA, "no pet"), label = c(`pets#1_3_1` = "Click to write the question text - Pet - Pet 3 - name")), 
    `pets#2_1_1` = structure(c(3, 0), label = c(`pets#2_1_1` = "Click to write the question text - Pet - Pet 1 - age")), 
    `pets#2_2_1` = structure(c(NA, NA), label = c(`pets#2_2_1` = "Click to write the question text - Pet - Pet 2 - age")), 
    `pets#2_3_1` = structure(c(NA, "x"), label = c(`pets#2_3_1` = "Click to write the question text - Pet - Pet 3 - age")), 
    Q9 = structure(c("was super awesome, but im having problems with this report :/", 
    "i dont know what im doing here"), label = c(Q9 = "Decribe how you felt today:"))), row.names = c(NA, 
-2L), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), column_map = structure(list(qname = c("StartDate", 
"EndDate", "Status", "IPAddress", "Progress", "Duration (in seconds)", 
"Finished", "RecordedDate", "ResponseId", "RecipientLastName", 
"RecipientFirstName", "RecipientEmail", "ExternalReference", 
"LocationLatitude", "LocationLongitude", "DistributionChannel", 
"UserLanguage", "name1", "name2", "yob", "mail", "Q5_1", "Q5_2", 
"Q5_3", "q1", "q2", "pets#1_1_1", "pets#1_2_1", "pets#1_3_1", 
"pets#2_1_1", "pets#2_2_1", "pets#2_3_1", "Q9"), description = c("Start Date", 
"End Date", "Response Type", "IP Address", "Progress", "Duration (in seconds)", 
"Finished", "Recorded Date", "Response ID", "Recipient Last Name", 
"Recipient First Name", "Recipient Email", "External Data Reference", 
"Location Latitude", "Location Longitude", "Distribution Channel", 
"User Language", "First name", "Birth Name", "Year of birth", 
"e-mail:", "Some scales - question1", "Some scales - question2", 
"Some scales - question3", "Example of a conditional item, where the YES answer leads to an other question;", 
"So... you clicked yes, right?", "Click to write the question text - Pet - Pet 1 - name", 
"Click to write the question text - Pet - Pet 2 - name", "Click to write the question text - Pet - Pet 3 - name", 
"Click to write the question text - Pet - Pet 1 - age", "Click to write the question text - Pet - Pet 2 - age", 
"Click to write the question text - Pet - Pet 3 - age", "Decribe how you felt today:"
), main = c("Start Date", "End Date", "Response Type", "IP Address", 
"Progress", "Duration (in seconds)", "Finished", "Recorded Date", 
"Response ID", "Recipient Last Name", "Recipient First Name", 
"Recipient Email", "External Data Reference", "Location Latitude", 
"Location Longitude", "Distribution Channel", "User Language", 
"First name", "Birth Name", "Year of birth", "e-mail:", "Some scales", 
"Some scales", "Some scales", "Example of a conditional item, where the YES answer leads to an other question;", 
"So... you clicked yes, right?", "Click to write the question text", 
"Click to write the question text", "Click to write the question text", 
"Click to write the question text", "Click to write the question text", 
"Click to write the question text", "Decribe how you felt today:"
), sub = c("", "", "", "", "", "", "", "", "", "", "", "", "", 
"", "", "", "", "", "", "", "", "question1", "question2", "question3", 
"", "", "Pet - Pet 1 - name", "Pet - Pet 2 - name", "Pet - Pet 3 - name", 
"Pet - Pet 1 - age", "Pet - Pet 2 - age", "Pet - Pet 3 - age", 
""), ImportId = c("startDate", "endDate", "status", "ipAddress", 
"progress", "duration", "finished", "recordedDate", "_recordId", 
"recipientLastName", "recipientFirstName", "recipientEmail", 
"externalDataReference", "locationLatitude", "locationLongitude", 
"distributionChannel", "userLanguage", "QID1_TEXT", "QID2_TEXT", 
"QID3_TEXT", "QID4_TEXT", "QID5_1", "QID5_2", "QID5_3", "QID6", 
"QID7", "QID8#1_1_1", "QID8#1_2_1", "QID8#1_3_1", "QID8#2_1_1", 
"QID8#2_2_1", "QID8#2_3_1", "QID9_TEXT"), timeZone = c("Europe/Berlin", 
"Europe/Berlin", NA, NA, NA, NA, NA, "Europe/Berlin", NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA), choiceId = c(NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, 
-33L), class = c("tbl_df", "tbl", "data.frame")))

我想做的是创建一个 PDF 报告,其中包含每个用户的所有问题标签和相应的回复(按行)- 格式很好,便于阅读。

我遇到了这个问题:但想进一步修改生成的文件名,但最终出错了。

文件名是我想要的,但是

1.打印的 table 是水平方向而不是垂直方向。 2. 打印列名而不是列标签。

这是我生成 pdf 的代码

for(i in 1:nrow(df)){
  data <- slice(df, i)
  rmarkdown::render('test.Rmd',
                    output_file = paste(data$name2, "_", data$name2, "_", data$yob, "_", data$StartDate, 
                                        '.pdf', sep=''))
  i <- i + 1
}

test.Rmd

---
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage{wrapfig}
- \usepackage{float}
- \usepackage{colortbl}
- \usepackage{pdflscape}
- \usepackage{tabu}
- \usepackage{threeparttable}
- \usepackage{threeparttablex}
- \usepackage[normalem]{ulem}
- \usepackage{makecell}
- \usepackage{xcolor}
title:  "Pacjent: `r data$name1` `r data$name2`" 
author: "YOB: `r data$yob`; e-mail: `r data$mail`" 
date: "date: `r data$StartDate`"
output:
  pdf_document:
  toc: false
editor_options: 
  chunk_output_type: console
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo =FALSE)
```

```{r}
library(kableExtra)
library(strengejacke)
library(tidyverse)
```

```{r}
kbl(data, longtable = T, booktabs = T) %>% kable_styling(latex_options = c("repeat_header", "striped"), full_width = F) %>%
  column_spec(1, width = "10em") %>%
  column_spec(2, width = "30em")
```

Rmarkdown 文档有参数(params in the yaml header)。 在这里,它是一个列表,它是 df 的一行,因此是一个人。 此列表在装帧后为垂直对齐的长格式,准备好由 kable 打印。 可以使用 names(x) <- x %>% attr("label").

通过属性标签设置名称

文件test.Rmd:


---
title:  "Pacjent: `r data$name1` `r data$name2`" 
author: "YOB: `r data$yob`; e-mail: `r data$mail`" 
date: "date: `r data$StartDate`"
params:
  data: NULL
output: pdf_document
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(kableExtra)
library(tidyverse)
names(data) <- data %>% map(~ .x %>% attr("label"))
data %>%
  # list to long format table (vartically aligned)
  enframe() %>%
  mutate(value = value %>% as.character()) %>%
  kable() %>%
  kable_styling(latex_options = "scale_down")

R - 代码:

for (i in 1:nrow(df)) {
  data <- slice(df, i) %>% as.list()
  rmarkdown::render("test.Rmd",
    params = list(data = data),
    output_file = paste(data$name2, "_", data$name2, "_", data$yob, "_", data$StartDate,
      ".pdf",
      sep = ""
    )
  )
}

示例结果: