タグ:filter

第2章ではデータハンドリングの基礎について紹介してきました。

【2-1】Rのfor関数、apply関数を使ってまとめて標準偏差などの統計量を求める方法

【2-2】Rのmutate関数を使って列の追加や修正を行う



今回は上記の復習として実際にデータを前処理し、集計をかけるところまで行います。

スクリーンショット 2019-02-08 10.33.40


1.データの準備

前回同様FIMのデータを使います。

FIM.xlsx 

今回は「入院時, 1ヶ月後, 退院時」全てのタブの使います。

スクリーンショット 2019-02-19 22.25.41


ダウンロードした後、プロジェクトの指定フォルダにファイルを移動させます。

プロジェクトの使い方がわからない場合は【1-6】Rstudioのプロジェクトについて解説しますをご参照ください。


まだ複数のデータを結合する方法を紹介していません。以下のコードを実行してください。

#必要なパッケージを読み込む
library(tidyverse)
library(readxl)

#それぞれのタブのデータフレームを作る
fim_in <- read_excel("FIM.xlsx", sheet = "入院時")
fim_1 <- read_excel("FIM.xlsx", sheet = "1ヶ月")
fim_out <- read_excel("FIM.xlsx", sheet = "退院時")

#bind_rows関数で3つのデータフレームを縦につなげる
fim <- bind_rows(fim_in, fim_1, fim_out)

bind_rows関数は複数のデータフレームを縦につなげる関数です。
fimという変数に入院時、1ヶ月、退院時全てのデータを縦につなげました。

これで準備完了です。


2.今回の目標

データにはFIM(18項目 + 運動合計 + 認知合計 + 全体の合計)のデータがあります。

更に今回同じ患者に3回反復測定を行っています。


<目標>
  • FIM各項目の平均点が入院時→1ヶ月→退院時でどう変化しているのかを表にする



課題①

まずデータの確認を行います。
  1. head関数、str関数を使ってデータを確認します。

回答は下にスクロールするとあります↓















head(fim)
スクリーンショット 2019-02-25 3.26.39

str(fim)
スクリーンショット 2019-02-25 3.27.15




課題②

データをlongデータに変えます。

まず列名と列番号を取得します。

t関数(またはdata.frame関数)とnames関数を組み合わせて列名と列番号を取得します。














t(names(fim))
スクリーンショット 2019-02-25 3.27.40

または
data.frame(names(fim))
スクリーンショット 2019-02-25 3.28.03



課題③

次はlongデータに変更します

  • パイプ演算子(%>%)を使います
  • 時期はbind_rows関数を使って縦に結合したので既にlongデータになっています
  • fimの「食事」〜「FIM全体」の列をlongデータに変えます
  • 今回はkeyの列名を「項目」、valueの項目を「点数」とします
  • 「項目」のfactorの要素を五十音順にせず、列で並んだ順で表示するようにします
















fim %>% 
  gather(5:25, key = 項目, value = 点数, factor_key = TRUE)
スクリーンショット 2019-02-25 3.55.14







課題④

次はsummarize関数を使い集計します。

  • fim_summarizeという変数名に作ります
  • 各項目が時期によってどう変化するのかが見たいのでした
  • 結果が項目→時期→点数と並ぶようにします。
  • 出た結果を見ると1箇所望まない結果になっている箇所があります。どこでしょう。














fim_summarize <- fim %>% 
  gather(5:25, key = 項目, value = 点数, factor_key = TRUE) %>% 
  group_by(項目,時期) %>% 
  summarize(平均 = mean(点数), 標準偏差 = sd(点数))
fim_summarize
スクリーンショット 2019-02-25 3.35.13



課題⑤
時期を見ると1ヶ月→退院時→入院時となっています。

時期のclassを確認します。















class(fim_summarize$時期)




課題④のコードに1行足して時期をfactor型に変え、入院時→1ヶ月→退院時の順に並ぶようにしてください。



















fim_summarize <- fim %>% 
  mutate(時期 = factor(時期, levels = c("入院時", "1ヶ月", "退院時"))) %>% 
  gather(5:25, key = 項目, value = 点数, factor_key = TRUE) %>% 
  group_by(項目,時期) %>% 
  summarize(平均 = mean(点数),
  標準偏差 = sd(点数))
fim_summarize
スクリーンショット 2019-02-25 3.29.54




課題⑥

今回の結果から「運動合計」「認知合計」「FIM合計」を取り除くにはどうすればいいでしょう。
fim_summarizeをつかって求めてください。
  • fim_summarize2 という変数名に作ります。
  • filter関数を使います
  • もし困ったら下の図を参考にしてください。
スクリーンショット 2019-02-11 2.04.40




















fim_summarize2 <- fim_summarize %>% 
  filter(!項目 %in% c("運動合計", "認知合計", "FIM合計"))
スクリーンショット 2019-02-25 3.31.41


まとめ

今回は第2章の一部の復習を行いました。

第2章では他にもifelse関数やcase_when関数を使って新たな変数名を作ったり、select関数で列を抽出しています。

今回のデータでも年代を作ったり、年代ごとにグループ分けすることも可能です。



fim %>% 
  mutate(年代 = cut(.$年齢, 
                  breaks = c(50, 60, 70, 80, 90),
                  right = FALSE, 
                  include.lowest = TRUE,
                  labels = c("50代", "60代", "70代", "80代")),
         年代 = as_factor(年代),
         時期 = factor(時期, levels = c("入院時", "1ヶ月", "退院時"))) %>% 
  gather(食事:FIM合計, key = 項目, value = 点数, factor_key = TRUE) %>% 
  group_by(時期, 項目, 年代) %>% 
  summarize(平均 = mean(点数), 
            標準偏差 = sd(点数),
            人数 = n())

スクリーンショット 2019-02-25 3.44.47


n関数はまだ紹介していませんでしたが、グループの数を表示することができます。
それ以外は過去の記事で紹介したものなので、まだしっくりこない方はサイトマップから過去の記事を探してみてください。



また色々な切り口があると思いますので、ぜひ色々試してみてください。


Rで集計やグラフ作成を行う場面は多くあります。

その際、元の表から分析に使いたい列や行だけを抽出したり、「男性だけを取り出す」みたいに様々な条件にあった行だけを抽出することが必要になります

今回はRで指定した列や行だけを取り出すselect関数、slice関数、filter関数を紹介します。
これらはtidyverseパッケージ内にあるdplyrパッケージの機能です。



今回使う架空のデータは前回と同じものを使用します。

年齢、性別、病名が入っています。
下のコードをまとめてスクリプトにコピペして実行してください。
library(tidyverse)
set.seed(1) 年齢 <- floor(rnorm(100,60,20)) 性別 <- sample(c("男性","女性"),100,replace = TRUE) 病名 <- sample(c("脳梗塞", "脳出血", "骨折", "靭帯損傷","心筋梗塞"), 100, replace = TRUE) data <- data.frame(年齢,性別,病名) head(data)

スクリーンショット 2019-02-10 22.48.49



1.指定した列を抽出するselect関数

select(データの変数名, 選択する列)

スクリーンショット 2019-02-13 20.15.20


select関数では縦の列を抽出します。

列名または列番号で選択します(" "をつけなくてOK)。

もしくは使わない列を選ぶこともできます。

そのため以下の3つのコードは全て同じ結果になります。
data_A <- data %>% 
  select(1,2)
head(data_A)

data_A <- data %>% 
  select(年齢,性別)
head(data_A)

data_A <- data %>% 
  select(1,性別)
head(data_A)

data_A <- data %>% select(-3) head(data_A)

列名で指定する場合は""で囲む必要はないですが、大文字や小文字など間違えないことが大切です。

また列番号の場合「何列目かなんてわからない…」ということもよくあります。

列名と列番号の一覧を知りたい時はt関数とnames関数を使うと便利です
t(names(data))
スクリーンショット 2019-02-13 20.28.22



応用編

応用①
もし列名が連番ならを使います。1番目〜5番目なら1:5と書きます。
select(1:5)

応用②
もっと選びたい列があって1番目と5番目〜10番目と13番目を使いたい場合は以下になります。
select(1, 5:10, 13)

応用③

インデックスという考え方で、選ぶ列番号を入れた変数を予め作成する方法があります。

data %>%
index <- c(1, 5:10, 13)
select(index)
スクリーンショット 2019-02-13 23.31.02


先にindexという変数名を作り、そこに指定する列を選びます。

Rを紹介する本やサイトではindexindという変数名で見かけることがありますが、もちろん好きな変数名で構いません。

indexの便利なところはindexを変えるだけで、本体のコードは1つも変わらないところにあります。

スクリーンショット 2019-02-13 21.08.16

このような考え方は色々な場面で使われます。

特に繰り返しの作業で効果を発揮します。



2.指定した行を抽出するslice関数

slice(データの変数名選択する列)

slice関数はselect関数の行バージョンです。

ただ条件で絞るのはslice関数でなく次に紹介するfilter関数になります。

silce関数は10万桁あって処理に時間かかるから、いきなり全部使わず1000行だけ切り取って、プログラムが動くかどうかテストしてみようみたいな場合に使えます。

他にも下のようなExcelをファイルを読み込むことになってしまい、1行目いらない!下の平均の行いらない!など切り取る列が決まってるときに使います。

スクリーンショット 2019-02-13 21.47.00

slice(2:7)はslice(-1,-8)でもOKです。



3.指定した条件を抽出するfilter関数

filter(データの変数名条件1,条件2)

filter関数は条件にあった行を抽出します。

data_B <- data %>% 
  filter(病名 %in% c("骨折", "靭帯損傷"))
head(data_B)
スクリーンショット 2019-02-13 21.45.33


前回の記事でも出ましたが、条件を付ける場合は演算子を使います。

スクリーンショット 2019-02-11 2.04.40
使い方に自身がない場合はRで数値を複数のカテゴリーに分類するifelse関数、case_when関数、cut関数を紹介しますをご参照ください。


複数の条件で絞る場合

filter関数で複数条件の場合は3つ方法があります。

, でつなぐ

filter関数はfilter(データの変数名条件1,条件2)という形式なので、カンマを使ってつなげることができます。

data_B <- data %>% 
  filter(病名 %in% c("骨折", "靭帯損傷") ,
         性別 == "女性" ,
         年齢 < 60)

%>%でつなぎ、filter関数を重ねる

filter関数は複数あって悪いことはないので、素直に%>%でつなげる方法ことも可能です。
メリットとしてはとりあえずわかりやすいのと、考えた順にコードを追加できるところでしょうか。

下のコードで①と同じ結果になります。
スクリーンショット 2019-02-13 21.56.55


&| で条件を付け加える

& や | でつなぐこともできます。演算子の前後に , は入れません。
今までの方法は全て「かつ」という意味でつないでいたので、「または」の意味でつなぎたい時は | でつなぎましょう。

これも①②と同じ結果になります。
スクリーンショット 2019-02-13 23.10.11



まとめ

今回はselect関数、slice関数、filter関数を紹介しました。

これらの関数は集計やグラフを作成するときによく使います。

今後も出てくる予定なのでわからなくなったら復習に使ってください。




↑このページのトップヘ