R跨多个列的多项选择调查问题的频率表

des*_*hen 1 r survey multi-select reshape

我想对R中的调查问题做一个相当普通的分析,但陷入了中间。

想象一个调查,要求您回答与某些功能相关联的品牌(例如,“品牌”可以是PlayStation,XBox ...,功能可以是“速度”,“图形” ...每个品牌可以在哪里检查了几个功能,也称为多选)。例如。在这里是这样的:https : //www.harvestyourdata.com/fileadmin/images/question-type-screenshots/Grid-multi-select.jpg

您通常将这些问题称为多选网格或矩阵问题。

无论如何,从数据角度来看,这类数据通常以宽格式存储,其中每行*列的组合是一个变量,其编码为0/1(如果调查参与者未选中该框,则为0,否则为1)。

假设我们有5个品牌和10个商品,则总共有50个变量,理想情况下遵循一个很好的结构化命名方案,例如item1_column1,item2_column1,item3_column1,[...],item1_column2等。

现在,我想一次迭代分析(频率表)所有这些变量。我已经在问题包中找到了cross.multi.table函数。但是,它仅允许基于单个因素分析所有项目。我需要的是同时允许多列。

有任何想法吗?我是否可能缺少另一个软件包中的函数,或者可以使用tidyverse甚至使用cross.multi.table函数轻松完成此操作?

使用此数据作为测试输入:

dat = data.frame(item1_column1 = c(0,1,1,1),
                 item2_column1 = c(1,1,1,0),
                 item3_column1 = c(0,0,1,1),
                 item1_column2 = c(1,1,1,0),
                 item2_column2 = c(0,1,1,1),
                 item3_column2 = c(1,0,1,1),
                 item1_column3 = c(0,1,1,0),
                 item2_column3 = c(1,1,1,1),
                 item3_column3 = c(0,0,1,0))
Run Code Online (Sandbox Code Playgroud)

我希望这个输出:

         column1    column2    column3
item1    3          3          2
item2    3          3          4
item3    2          3          1
Run Code Online (Sandbox Code Playgroud)

或理想的比例/百分比:

         column1    column2    column3
item1    75%        75%        50%
item2    75%        75%        100%
item3    50%        75%        25%
Run Code Online (Sandbox Code Playgroud)

Ron*_*hah 5

一种方法可能是将数据导入使用长格式gatherseparate基于列_group_by itemcolumn与计算的比例value列和spread数据,以宽格式。

library(dplyr)
library(tidyr)

dat %>%
  gather(key, value) %>%
  separate(key, into = c("item", "column"), sep = "_") %>%
  group_by(item, column) %>%
  summarise(prop = mean(value) * 100) %>%
  spread(column, prop)

#  item  column1 column2 column3
#  <chr>   <dbl>   <dbl>   <dbl>
#1 item1      75      75      50
#2 item2      75      75     100
#3 item3      50      75      25
Run Code Online (Sandbox Code Playgroud)

短一点(感谢@MM)

dat %>%
  summarise_all(~mean(.) * 100) %>%
  gather(key, value) %>%
  separate(key, into = c("item", "column"), sep = "_") %>%
  spread(column, value)
Run Code Online (Sandbox Code Playgroud)