在 R 中分析调查数据

Analyze survey data in R

您使用 R 中的哪个包和函数来分析调查数据? 我最感兴趣的是为 single choicemultiple choice 问题计算 percentages。此外,按 target groups.

过滤数据

single choice题看起来比较清楚。 但是,您如何处理 multiple choice 个问题(当问题在多个栏中时)? F.e.,问题 Pet 在 3 个单独的列中。

此外,有没有一种简单的方法可以在 original 数据和 weighted 数据之间切换?

df =data.frame(
  c(1,1,1,1, 1 ),
  c(0.99, 1.21, 0.83, 0.82, 2.3),
  c(16, 25, 34, 45, 74),
  c("Male", "Male", "Female", "Male", "Female"),
  c("Dog", "", "Dog", "", ""),
  c("Cat", "Cat", "", "Cat", "Cat"),
  c("", "Fish", "", "", "Fish")
)


names(df) = c("Respondent", "Weight", "Age","Gender","Pet_Dog", "Pet_Cat", "Pet_Fish")

我将通过指定您要执行的操作的构建块来给出答案。首先从权重问题开始:您使用 Weight 列的方式融入了您调用函数的方式。例如,base R 中的 table() 函数可以为您提供给定变量中每个类别的总计:

table(df$Gender)

## Female   Male 
##      2      3 

对于加权版本,您可以使用 wtd.table() from questionr:

library(questionr)
wtd.table(df$Gender, weights = df$Weight)

## Female   Male 
##   3.13   3.02

为了简单起见,您可以使用 wtd.table() 通过省略权重参数来给出 未加权 总计:

wtd.table(df$Gender)

## Female   Male 
##      2      3 

对于比例,你可以将 table 填入 prop.table():

prop.table(wtd.table(df$Gender))

## Female   Male 
##    0.4    0.6 

prop.table(wtd.table(df$Gender, weight = df$Weight))

##    Female      Male 
## 0.5089431 0.4910569 

请注意 prop.table() 的文档,这只是一个方便的包装器,用于将 table 除以其条目的总和:

This is really sweep(x, margin, margin.table(x, margin), "/") for newbies, except that if margin has length zero, then one gets x/sum(x).

对于子组过滤,它与往常一样:在数据框上使用您最喜欢的过滤策略,然后 运行 通过上面的过滤策略。对于 base R 选项,查看男性对鱼的回答:

with(df[df$Gender == "Male", ], prop.table(wtd.table(Pet_Fish, weights = Weight)))

##                Fish 
## 0.5993377 0.4006623 

解释是,关于鱼问题(男性)的(加权)回答中有 60% 是空白,另外 40% 表示有鱼。如果是我,我会将这些空白重新编码为“无鱼”或“none”或类似的东西,但这只是我的偏好。

您可能在问题中提到的另一条路线是做交叉表。您可以使用 two-way table 来实现这一点,只需在 wtd.table() 函数中提供两个变量即可。

prop.table(wtd.table(df$Pet_Fish, df$Gender, weights = df$Weight), margin = 2)

##         Female      Male
##      0.2651757 0.5993377
## Fish 0.7348243 0.4006623

此处,margin = 2 指定列的总和应为 1。然后您可以像这样将多个 table 粘合在一起,等等。

至于如何处理multi-choice的问题,就看你的了。如果回答是排他性的(即没有人拥有两种不同的宠物),那将是直截了当的;只需将变量合并在一起并使用上述技术即可。您的数据框没有 属性。一种可以考虑的方法是将它们保留为二进制变量并独立报告每个答案;例如,您可以将宠物问题视为三个独立的问题(狗 Y/N、猫 Y/N、鱼 Y/N)。或者,您可以将案例分解为宠物所有权的 8 种不同可能组合,并以这种方式重新编码变量。还有许多其他方法可以继续,哪种方法最好完全取决于您要在这些数据中呈现的内容。


编辑: 对于 multi-crosstabs 问题,我会使用 cbind() 方法。例如,我将发明一个 Age_recode 列,以便我可以在因子环境而不是数字环境中工作:

df$Age_recode <- c("Young", "Young", "Mid", "Mid", "Old")

具有多个因素的交叉表 table 可能是这样的:

cbind(prop.table(wtd.table(df$Pet_Fish, df$Gender, weights = df$Weight), margin = 2),
      prop.table(wtd.table(df$Pet_Fish, df$Age_recode, weights = df$Weight), margin = 2))

##         Female      Male Mid Old Young
##      0.2651757 0.5993377   1   0  0.45
## Fish 0.7348243 0.4006623   0   1  0.55

这显然有点麻烦,所以如果你想多次做这件事,那么编写一个函数来自动化它会更有好处。 questionr 中也可能有一些东西可以做到这一点,但我不知道那个库中的全部内容,所以我不能说。

请注意,一般来说,使用 cbind() 可能有点冒险,因为它会盲目地将 table 粘在一起,而不考虑行名称。在这种情况下没关系(我认为),因为 wtd.table()s 的行名称只是在传递给函数的第一个变量中找到的所有响应的字母顺序列表,并且 tables 应该匹配. (同样,我 认为 我在这里没有遗漏任何东西,但我可能遗漏了任何东西。)