使用 Tidyverse 跨多个列计算 REDCap 数据中特定字符串的频率

Using the Tidyverse to the count the frequency of a specific string in REDCap data across multiple columns

我经常收到来自 REDCap 调查的数据,在这些调查中,受访者可以“检查”>1 个对调查问题的回答。每个可能的响应都位于其自己的列中。我想总结一下检查每个响应选项(列)的频率。例如:

library(tidyverse)
set.seed(1234)
responses<-c("Checked", "Unchecked")
numobs<-10

my_example<-data.frame(id=1:10, 
                       Response_Option_A=sample(responses, numobs, replace=TRUE), 
                       Response_Option_B=sample(responses, numobs, replace=TRUE), 
                       Response_Option_C=sample(responses, numobs, replace=TRUE),
                       Response_Option_D=sample(responses, numobs, replace=TRUE),
                       stringsAsFactors = FALSE)

my_example
#>    id Response_Option_A Response_Option_B Response_Option_C Response_Option_D
#> 1   1         Unchecked         Unchecked         Unchecked           Checked
#> 2   2         Unchecked         Unchecked         Unchecked         Unchecked
#> 3   3         Unchecked         Unchecked         Unchecked           Checked
#> 4   4         Unchecked           Checked         Unchecked           Checked
#> 5   5           Checked         Unchecked         Unchecked           Checked
#> 6   6         Unchecked         Unchecked         Unchecked         Unchecked
#> 7   7           Checked         Unchecked           Checked           Checked
#> 8   8           Checked           Checked         Unchecked         Unchecked
#> 9   9           Checked         Unchecked         Unchecked         Unchecked
#> 10 10         Unchecked         Unchecked         Unchecked           Checked

我最初的想法是尝试这个,但它 returns 检查的回复总数,而不是每列中的数字。

my_example %>%
  select(starts_with("Response_Option_")) %>%
    summarise(checked=sum(.=="Checked"))
#>   checked
#> 1      13

reprex package (v0.3.0)

于 2020-08-10 创建

感谢您帮助有效地总结这些回复。

这是一种 tidyverse 方法来显示每列的响应总数,而不是按行。我假设,根据你对问题的措辞,这就是你要找的东西。还包括问题标签中包含的 starts_with() 函数。

我们可以使用 pivot_longer() 将响应特征从宽转向长,然后使用 group_by 定义采用现有 table 的变量并将其转换为分组 table 其中 summarise() 操作用于创建一个新的数据框,其中包含为分组变量的每个组合提供的行。

library(tidyverse)
set.seed(1234)
responses<-c("Checked", "Unchecked")
numobs<-10

my_example<-data.frame(id=1:10, 
                       Response_Option_A=sample(responses, numobs, replace=TRUE), 
                       Response_Option_B=sample(responses, numobs, replace=TRUE), 
                       Response_Option_C=sample(responses, numobs, replace=TRUE),
                       Response_Option_D=sample(responses, numobs, replace=TRUE),
                       stringsAsFactors = FALSE)

my_example %>% 
  pivot_longer(starts_with("Response_"), names_to = "Responses", 
               values_to = "value") %>% 
  group_by(Responses, value) %>%
  summarise(total_responses = n())


#> # A tibble: 8 x 3
#> # Groups:   Responses [4]
#>   Responses         value     total_responses
#>   <chr>             <chr>               <int>
#> 1 Response_Option_A Checked                 4
#> 2 Response_Option_A Unchecked               6
#> 3 Response_Option_B Checked                 2
#> 4 Response_Option_B Unchecked               8
#> 5 Response_Option_C Checked                 1
#> 6 Response_Option_C Unchecked               9
#> 7 Response_Option_D Checked                 6
#> 8 Response_Option_D Unchecked               4

reprex package (v0.3.0)

于 2020-08-10 创建

如果您只需要 Checked 响应,可以在 summarise() 操作之后添加以下代码行:

filter(value == "Checked")

#> # A tibble: 4 x 3
#> # Groups:   Responses [4]
#>   Responses         value   total_responses
#>   <chr>             <chr>             <int>
#> 1 Response_Option_A Checked               4
#> 2 Response_Option_B Checked               2
#> 3 Response_Option_C Checked               1
#> 4 Response_Option_D Checked               6

一个非常base R的解决方案是:

my_example$checked <- apply(my_example[,which(grepl('Response_Option_',names(my_example)))],1,
                            function(x) length(which(x=="Checked")))

输出:

   id Response_Option_A Response_Option_B Response_Option_C Response_Option_D checked
1   1         Unchecked         Unchecked         Unchecked           Checked       1
2   2         Unchecked         Unchecked         Unchecked         Unchecked       0
3   3         Unchecked         Unchecked         Unchecked           Checked       1
4   4         Unchecked           Checked         Unchecked           Checked       2
5   5           Checked         Unchecked         Unchecked           Checked       2
6   6         Unchecked         Unchecked         Unchecked         Unchecked       0
7   7           Checked         Unchecked           Checked           Checked       3
8   8           Checked           Checked         Unchecked         Unchecked       2
9   9           Checked         Unchecked         Unchecked         Unchecked       1
10 10         Unchecked         Unchecked         Unchecked           Checked       1

这也是@r2evans 的最佳方式:

my_example$checked <- rowSums(my_example[, grep("^Response_", colnames(my_example))] == "Checked")

它产生与之前相同的输出并且更具可读性。

检查 tidyREDCap 包。它有一堆函数来帮助处理检查所有来自 REDCap 的应用 变量。该包在 CRAN 上,github.io 上的网站在页面顶部的文章下拉列表中有小插曲。

您可以将 summariseacross 一起使用:

library(dplyr)
my_example %>%
  summarise(across(starts_with("Response_Option_"), ~sum(. == 'Checked')))

#  Response_Option_A Response_Option_B Response_Option_C Response_Option_D
#1                 4                 2                 1                 6

dplyr 的旧版本中,您可以使用 summarise_at :

my_example %>%
     summarise_at(vars(starts_with("Response_Option_")), ~sum(. == 'Checked'))