質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

RでExcelのピボットテーブルのような3次元のクロス集計を行いたいです

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,109

score 13

Rを使って3次元のクロス集計をしたいと考えています。
これまでExcelのピボットテーブルで行っていた作業をR上で行いたいというイメージです。

分析対象データ
1列目(果物)には"りんご"、"みかん"、"いちご"
2列目(食べ方)には"がむ"、"ジュース"、"そのまま"
3列目(被験者名)には被験者名(重複=繰り返しあり)
4列目(おいしさ)には得点(10点満点)
がランダムに10万行程度入っているイメージです。

☆教えて頂きたいこと1
集計に当たってまず、りんご*がむ、りんご*ジュース、りんご*そのまま、みかん+がむ・・・いちご*そのままのように5列目(果物*食べ方)に9種類のラベルを作成したいです。

現状:mutateやfilter関数を使うことまでは分かったのですが、どう書いていけばよいのか分かりません。

コード:
データ全体=p2018
1列目(果物)=ku りんごは0、みかんは1のような形式です
2列目(食べ方)=ta がむは0、ジュースは1のような形式です。
5列目(果物*食べ方)=kt

p2018 %>%
dplyr::filter(p2018$ku == 0, p2018$ta == 0)  %>%
dplyr::mutate(kt = 1)
p2018 %>%
dplyr::filter(p2018$ku == 0, p2018$ta == 1)  %>%
dplyr::mutate(kt = 2)
・・・kt=9まで続く
現状このようなコードを書いた後、p2018と入力するとktの列があると出力されるのですが、csv形式で出力するとkt列が出力されていません。

☆教えて頂きたいこと2
5列目(果物*食べ方)の9種類が被験者(3列目)ごとに平均何点なのかをクロス集計表で算出したいです。

現状:クロス集計をして度数を算出する方法はいくつか見つけました。aggregate関数を使い、被験者ごとの平均得点を求めることは出来たのですが、そこに”果物*食べ方”をクロスさせる方法が分かりません。
aggregateではなくdplyr関数を使った方が良いというような記載も見つけ、どうすれば良いかわからなくなっています。

コード:
被験者名=name
得点=sc
aggregate(p2018$sc, by=list(p2018$name), FUN=mean, na.rm = TRUE)

とすると、被験者ごとの平均得点を求めることは出来たのですが、ここに5列目(果物*食べ方)の変数をどう追加すればよいのかが分かりません。

今までRはExcelで整理したデータを統計にかける程度で使っており、R上でデータ整理することは結構難しいと感じている次第です。
どなたか教えて頂くことは出来ませんでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • KojiDoi

    2019/03/18 16:38

    これでは丸投げです。できたところまででいいですから貴方のRのコードを提示してください。

    キャンセル

  • stdio

    2019/03/18 16:40

    全部公開されても困るだけなので、質問のとことだけ抜粋してお願いします。

    キャンセル

  • 88yasu

    2019/03/18 16:48

    ご指摘いただきありがとうございます。
    どうやって質問したら良いかも分からない状態でした。
    コードを追記いたします。

    キャンセル

回答 1

checkベストアンサー

0

とりあえず一番目の質問について。考え方は、まず特定の1行に注目し、既存の列データから新しい列を合成することを考えます。ここでは単純にpaste関数を使えばいいでしょう。excelのconcatenate関数に似た働きをします。paste("a","b")は"a b"を返します。

これが確認できたら、データフレームの列全体を対象とした式を組みます。Rの世界では、df[,1]あるいはdf[,"ta"]あるいはdf$taの形式で、「1列目」あるいは「taと名付けられた列」を指定できます。そして、あたかも単値同士の演算を行うかのようなスタイルで、データの集合体(ベクトル)を相手にした演算を表現できます。これを利用してデータフレームに新しい列を簡単に追加定義できます。

次に2番めですが、aggregate関数を使うのが簡単でしょう。引数として、集計したい列(群)・識別したい条件(群)・関数を指定します。また、by=、fun=などパラメータ名を明示した指定も可能で、この場合はパラメータの順序が前後しても構いません。

dplyrはうまく使えばデータの流れがわかりやすくなって有用ですが、最初はとりあえず忘れていいです。dplyrがなければできない処理というのは基本的にありません。まずはRでのデータ取り回しの基本を理解しないと、かえって混乱すると思います。

まとめると、だいたい次のようなコードになると思います。

#とりあえずテストデータをでっちあげる。
testdf <- read.table(text="
ku  ta person    score
 1   1 Nishizumi 10
 1   1 Isuzu     25
 1   0 Reizei    30
 0   1 Takebe    22
 0   1 Akiyama   33
 0   0 Nishizumi 23
 1   0 Reizei    44
 0   0 Isuzu     32
 1   1 Nishizumi 45
 0   1 Isuzu     69
 1   0 Reizei    70
 0   1 Takebe    72
 1   1 Akiyama   74
 0   0 Akiyama   76
 1   0 Takebe    77
 0   0 Nishizumi 80",
header=T, stringsAsFactors=F)

# 5列目(kuta)追加
testdf$kuta <- paste(testdf$ku, testdf$ta)

# カテゴリごとの平均を出す
r <- stats::aggregate(
     testdf$score,                           # testdfのうちscore列だけを対象にする
     by = list(testdf$kuta, testdf$person),  # kutaとperson列でカテゴライズ
     FUN = mean
)

print(r)

# 結果をtab区切りファイルに書き出す
write.table(r, sep="\t", file="out.txt")

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/19 03:29

    質問の仕方を教えて頂いた上に、データを生成した上でコードを解説いただき本当にありがとうございます。
    pasteという関数を使って合成すること、by=listのあとにクロスしたい変数を書いていくことが理解できました。
    (自分が記載したコードにコピーの不足があったため再度追記いたしました)
    stats::と書く辺り、まだまだ理解できていないので自分で調べたいと思います。
    本当にありがとうございます!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る