68430


「被験者」「ポイント」「要素」の３つのカラムで出来たデータセットがあります。  
下画像のようなイメージです。

[![分析前のデータセット](https://i.stack.imgur.com/A12b6.png)](https://i.stack.imgur.com/A12b6.png)

「被験者」は A,B,C,D,E,F,G,H のいずれか  
「ポイント」は 1~23 の整数  
「要素」は 1~10 の整数

が入っています。

このデータをRを使って、  
被験者別（A,B,...,H）に、「1~23」の各ポイントでの要素の割合をクロス集計で出したいです。  
そしてそのクロス集計結果をCSVで出力したいです。

望んでいるイメージは以下のイメージです  
[![最終的に欲しいCSVデータのイメージ](https://i.stack.imgur.com/zvECx.png)](https://i.stack.imgur.com/zvECx.png)

* * *

自分で試したこと

①Rにデータフレームを読みこませる  
②クロス集計したいカラムをRに「要因」として指定する  
③「要素」カラムに入力されている1～10の値に具体的な名称をラベリング  
④割合をggplot2でグラフをして出力（今回の質問には無関係）

[code]

    #.csvファイルの読み込み
    All=read.csv("データセット.csv", header=TRUE)
    
    #分類コード(ポイント)が「変数」ではなく「要因」であることを指定
    All$要素=as.factor(All$要素)
    All$ポイント=as.factor(All$ポイント)
    
    #分類コード(要素)にラベリング
    All$要素 <- factor(All$要素, levels = c(1,2,3,4,5,6,7,8,9,10),
    labels = c("りんご", "みかん", "もも",  "ぶどう", "なし", "バナナ", "メロン", "さくらんぼ", "レモン","パイン"))
    
    #ggplot2というライブラリをインストール
    library(ggplot2)
    
    #参加者別パーセンテージ
    ggplot(All, aes(x=Point,y=Duration.ms., fill=要素))+geom_col(position="fill")+
      scale_y_continuous(labels=scales::percent)+
      ggtitle("ポイント毎での果物割合")  +
      ylab("%Duration")+
      facet_wrap(~Participant)
    
[/code]

##
[![ポイント毎での果物割合](https://i.stack.imgur.com/Y0UyJ.png)](https://i.stack.imgur.com/Y0UyJ.png)

この割合棒グラフに対応するCSVファイルを出力したいと思っています。  
やり方をご存じの方がいらっしゃれば、ご助言いただきたく、よろしくお願いします。


CC BY-SA 4.0
2020-07-09T03:58:53.183
68422
2020-07-09T08:19:30.033
41006
question
r csv
Rを使ってデータセットをクロス集計し、結果をCSVで出力したい。


ggplot2のほうは説明されてない列が使われていてよくわからないですが,
「被験者」「要素」「ポイント」と言う列でグループ集計をしたいということでよろしいですね? お答えする以外にもいくつか方法はありますが,
`tidyverse` を使うのが日本語の情報も充実していてやりやすいと思います.

以下, わかりやすくするためにところどころ区切って少し冗長な書き方で例を示します

[code]

    require(tidyverse)
    
    # 疑似データ作成
    set.seed(42)
    All <- expand_grid(
      `被験者` = LETTERS[1:8],
      `ポイント` = 1:23,
      `要素` = 1:10
    ) %>% sample_n(size = 4000, replace = T)
    
    # グループ集計
    
    # 被験者・要素・ポイントごとにカウントした count 列追加
    df_summary <- All %>% group_by(`被験者`, `ポイント`,`要素`) %>%
      summarise(count = n(), .groups="drop")
    
    # 被験者・ポイントごとの合計要素カウントを計算した total 列追加
    df_summary <- df_summary %>%
      group_by(`被験者`, `ポイント`) %>% mutate(total = sum(count)) %>% ungroup
    
    # 割合計算した ratio 列追加
    df_summary <- mutate(df_summary, ratio = count / total) %>%
      select(-count, -total)
    
    # 横に伸ばす, ポイントが存在しない場合は 0 で表示
    # その後 1-10 の順序を整える
    df_summary_wide <- df_summary %>% pivot_wider(names_from = `要素`, values_from = ratio, values_fill = 0) %>%
      select(`被験者`, `ポイント`, num_range(prefix = "", 1:10))
    
    
    # パーセント表記で表示
    # 表示桁は accuracy で調整
    mutate(df_summary_wide, `ポイント` = as.character(`ポイント`)) %>%
      mutate(across(where(is.numeric), ~scales::percent(.x, accuracy = 1)))
    
[/code]

出力はこんな感じです. 後は好きな方法でエクスポートすれば良いですが, `write.csv` を使う場合は `quote = F`
を設定したほうがよいです.

[code]

    # A tibble: 184 x 12
       被験者 ポイント `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`   `10` 
       <chr>  <chr>    <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
     1 A      1        10%   10%   16%   13%   0%    10%   6%    23%   3%    10%  
     2 A      2        9%    18%   9%    5%    5%    14%   9%    14%   14%   5%   
     3 A      3        5%    10%   0%    20%   15%   20%   10%   0%    10%   10%  
     4 A      4        5%    9%    18%   9%    5%    5%    14%   5%    23%   9%   
     5 A      5        12%   12%   6%    6%    12%   12%   6%    6%    24%   6%   
    
[/code]

注意点として, グループ化する3列の値の組み合わせのうちデータフレームにないものがあれば, 最後の表から抜けてしまいます. そのようなデータであれば,
集計前に要素=0のダミー行を追加してください


CC BY-SA 4.0
2020-07-09T08:12:38.673
68430
2020-07-09T08:19:30.033
2020-07-09T08:19:30.033
40575
40575
68422
answer