PsyStat.

Just for fun.

アンケートや調査時に回答カテゴリごとの回答数(回答頻度)を集計したい

こんにちは。

お久しぶりです。

いきなりですが、アンケートや質問調査などを集計するときに便利な関数を備忘録的にまとめます。

base内のtabulate関数についてです。

やりたいこと

複数の変数(回答者・項目)の回答カテゴリの回答数(回答頻度)を集計したい

→ table関数で解決です

→ ただ、全変数の回答カテゴリ数が揃っていないと結構面倒(だと思っていました)

こんなときにどうすればよいのか?

はい、やっていきます。

簡単な場合

今回はltmパッケージのScienceデータを使います

回答者 x 項目 の回答データ(今回は4件法)になっています.

library(ltm)
data("Science")

dat <- 
  Science |>  
  lapply(as.numeric) |> 
  as.data.frame()

## Work項目に関する回答を集計したい場合
table(dat$Work)

 #  1   2   3   4 
 # 33  98 206  55 

複数列の場合 1

全ての変数(項目)で全ての回答カテゴリが使われている場合

dat |> 
  apply(2,table) |> 
  as.data.frame() ## stringsAsFactors = TRUE となっているので、注意が必要な場合があります

#   Comfort Environment Work Future Technology Industry Benefit
# 1       5          29   33     14         18       10      21
# 2      32          90   98     72         91       47     100
# 3     266         145  206    210        157      173     193
# 4      89         128   55     96        126      162      78

このように、項目ごとの回答カテゴリ(1~4)への回答頻度を集計したデータフレームを返してくれます。

複数列の場合 2

一部の変数(項目)で一部の回答カテゴリが使われていない場合

まず、ゆがんだデータを作成します.

dat2 <- dat

## わざとデータをゆがませる(Work列で1の回答を全て2に上書き)
dat2$Work <- ifelse(dat2$Work==1,2,dat2$Work) 

table(dat$Work)
 #  1   2   3   4 
 # 33  98 206  55 

table(dat2$Work)
#   2   3   4 
# 131 206  55 

ゆがんだデータdat2ができました。

ここで先ほどの集計方法を使ってみます。

dat2 |> 
  apply(2,table) |> 
  as.data.frame()

 # (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  でエラー: 
 #   引数に異なる列数のデータフレームが含まれています: 4, 3 

このように変数(項目)間のカテゴリ数があわなくなるので、データフレームができないと言われます。

私はこの問題に結構前から悩まされていて、いろいろと面倒なことをやって解決していたのですが、

base内のtabulate関数で解決できました。

dat2 |> 
  apply(2,tabulate, nbins=4) ## 項目ごとに頻度を計算してくれます

#      Comfort Environment Work Future Technology Industry Benefit
# [1,]       5          29    0     14         18       10      21
# [2,]      32          90  131     72         91       47     100
# [3,]     266         145  206    210        157      173     193
# [4,]      89         128   55     96        126      162      78

## 回答者(行ごと)の場合も同様に可能(返り値は、カテゴリ数 x 回答者の行列)
dat2 |> 
  apply(1,tabulate, nbins=4)

nbinsは、最大カテゴリ数(今回の例では4件法なので4)を指定します。

この関数によって、回答頻度が0件もきちんと補ってくれて集計することができました。

注意すべき点

ヘルプに書いてあるとおりですが、table関数とは違って、負の数や0は集計しません(以下の3番目の例)。

また、nbinsと最大カテゴリ数が合っていないと(nbins<最大カテゴリ数の場合)、nbins以降は無視されます(以下の4番目の例)。

参照先:ヘルプの例の実行例

tabulate(c(2,3,5))
# > [1] 0 1 1 0 1

tabulate(c(2,3,3,5), nbins = 10)
# > [1] 0 1 2 0 1 0 0 0 0 0

tabulate(c(-2,0,2,3,3,5))  # -2 and 0 are ignored
# > [1] 0 1 2 0 1

tabulate(c(-2,0,2,3,3,5), nbins = 3)
# [1] 0 1 2

以上です。

このような集計を使う人がどれだけいるかわかりませんが。何かの役に立てば。

久々のEnjoy!