Rによるデータ解析(その2)列の選択・削除・列を分ける・結合・名前の変更・重複した行の削除・列を新しく作る。

日付;2022/04/25(月)

ここでは、Rを使って、データセットを整形するための方法を述べる。基礎医学・生物学で利用するデータセットはそんなに大きくないし、複雑でもない。もし何かおかしなレコードがあれば、個別に対応することも可能である。したがって、自分はここに述べるような方法で十分に実験データやTCGAの解析ができていた。これでRを使ったデータ整形はだいたいイケるのではないかと思っている。自分は主にtidyverseのdplyrを使っている。その理由は圧倒的に簡単だからである。他のものを無理して使う必要もない。

注意点だが、以降に述べる各関数の前にライブラリ名が付いたり付かなかったりしているが、それは自分がよく使っているライブラリによりマスクされてしまい、時々エラーがでるためである。必要に応じて消したりつけたりする必要がある。

使うライブラリ(tidyverse)

R
library(tidyverse)

コツ

色々とライブラリを読み込んでいると、単純な名前の関数名が他のライブラリの同じ関数名でマスクされることがあるので、もしそうなった場合はその関数の前にdplyr::などをつけて限定してやったら良い。

データの型を設定する(as.numeric())

特にこれはやらなくても良いかも知れないが、時々数字のデータであるべきものが文字列になっていたり、その逆になっていたりするので目的に合わせて行ったほうが良い。as.character()、as.integer()、as.logicalなんかも必要だったりする。

R
Original$Day_after_injection <- as.numeric(Original$Day_after_injection)
Original$Long <- as.numeric(Original$Long)
Original$Short <- as.numeric(Original$Short)
Original$Volume <- as.numeric(Original$Volume)
Original$Ratio_volume <- as.numeric(Original$Ratio_volume)
Original$Ratio_body_weight <- as.numeric(Original$Ratio_body_weight)
Original$Tumor_Weight <- as.numeric(Original$Tumor_Weight)
Original$Spleen_Weight <- as.numeric(Original$Spleen_Weight)

必要な列の選択(dplyr::select())

以下は、OriginalというデータセットからGeneid, DMSO1, DMSO2, DMSO3, DMSO4, ON2, ON3, ON3, ON4, ON5という列を選んでNew_Datasetという新しいデータセットを作る、という意味である。

R
New_Dataset <- Original %>% dplyr::select("Geneid", "DMSO1", "DMSO2", "DMSO3", "DMSO4", "ON2", "ON3", "ON4", "ON5")

不要な列の削除(dplyr::select(-one_of()))

以下は、Originalというデータセットからid、gene_id、versionという列を削除して、新しくNew_datasetというデータセットを作るという意味である。

R
New_Dataset <- Original %>% dplyr::select(-one_of("id", "gene_id", "version"))

列を分ける(separate())

たまに、Gene IDのバージョンが邪魔だったりする。そんなときにこれが使える。以下はgene_idという列(に入っているデータ)を、” . “で切って、”id”と”version”という2つの列に分けるという意味である。

R
New_dataset <- Original %>% tidyr::separate("gene_id", sep = "\\.", remove = FALSE, into = c("id", "version"))

2つのデータセットの結合(tibble型のデータ)(right_join(), left_join(),full_join(), inner_join())

以下は2つのデータセットを結合するという意味である。なお、これはas.tibble()で作られた型のデータを扱うことができる。data.frame()で作られたデータは扱えないので、もしdata.frame()やc()で作られたようなデータをdplyrで扱うためには、まずはNew_datasetをas.tibble()によりtibble型にする。これは後ほど述べておく

R
New_dataset <- tibble::as_tibble(New_dataset)
New_dataset <- right_join(Dataset1,Dataset2)

他にはleft_join()とかfull_join()とかを、必要に応じて使用すれば良い。2つのデータセットの共通因子を抽出する場合は、inner_join()が一番良いと思う。

2つのデータセットの結合(データフレームの場合)(cbind())

data.frame()で作られたデータの結合は以下のようにcbind()を用いる。DEseq2なんかはこっちを使う必要があったりする。説明の順序が逆になったが、こういうのが上述のdata.frame()で作られたデータである。

R
column <- c("DMSO1", "DMSO2", "DMSO3", "DMSO4", "ON2", "ON3", "ON4", "ON5")
condition <-c("control","control", "control", "control", "treated", "treated", "treated", "treated")
type <- c("paired-end", "paired-end", "paired-end", "paired-end", "paired-end", "paired-end", "paired-end", "paired-end")
coldata <- cbind(column, condition, type)

列の名前を変える(dplyr::rename())

以下は、mnt/Output_STAR/DMSO1_RAligned.out.sorted.bamという冗談では済まない列名をDMSOに変えるという意味である。ときどき、STARを走らせた後にやってしまう。

R
New_dataset <- Original %>% dplyr::rename("DMSO" = "/mnt/Output_STAR/DMSO1_RAligned.out.sorted.bam")

同一列内の重複を除く(distinct())

同じ遺伝子名(ensemblなどでは、Gene IDやバージョンは違うが、遺伝子名が同じということが起こる。もちろん、カノニカルな方を選ぶ。)などを除くときに使用する。

R
New_dataset <- Original %>% distinct(Case_ID, .keep_all = TRUE)

ある条件のデータ(行)を抽出する(dplyr::filter())

データセットOriginalから、filter()内の条件に合うデータを抽出して、新しいデータセットNew_datasetを作るという意味。例えば、一番上のスクリプトは「Volumeという列の数字が0ではないヤツを抽出する」という意味。ANDは&、ORは|、==は等しい、!=は等しくない、である。

R
New_dataset <- Original %>% dplyr::filter(Volume != 0)
New_dataset <- Original %>% dplyr::filter(Drug != "NA")
New_dataset <- Original %>% dplyr::filter(Drug_ID != "DMSO_Extra_1" & Drug_ID != "DMSO_Extra_2")
New_dataset <- Original %>% dplyr::filter(padj < 0.05 & log2FoldChange > 0)
New_dataset <- Original %>% dplyr::filter(gene_name == "Gene1" | gene_name == "Gene2" |gene_name == "Gene3" | gene_name == "Gene4" | gene_name == "Gene5")

2つの列を一つに結合する(unite())

実験の都合上、マウスの個別ID(これはメインキーというか、メインIDになる)に加えて、各薬剤投与群ごとの個別ID(行ってみればサブID)が必要になる場合がある。マウスの個別IDはほとんどの実験でつけてあるはず(メインID、メインキーなので)なので、その個別IDとそのマウスに投与した薬剤名を記載した列を結合することで、サブIDが出来上がる。その場合は以下のuniteが使える。

R
Analysis <- Analysis %>% tidyr::unite(Drug, Mouse_ID, col = "Drug_Mouse_ID", remove = "FALSE")

以下は、AnalysisというデータセットのDrugとMouse_IDという列を結合して、新しくDrug_Mouse_IDをという列を付けるという意味である。尚、この関数はデフォルトでセパレーターとしてアンダーバーがついている。また、デフォルトでremoveがTRUEになっているので、そのままではDrugとMouse_IDという元の列が削除されてしまう。そうならないために、remove = “FALSE”としたほうが良いように思う。

新しい列を追加する(mutate())

単純に列を追加したい場合、mutate()が使える。以下はOriginal_datasetというデータセットにNivolumabという文字列が入ったDrugという列と、NSGという文字列が入ったMouseという列を加えて、新しくNew_datasetというデータセットを作る、という意味。

R
New_dataset <- Original_dataset %>%  mutate(Drug = "Nivolumab", Mouse = "NSG")

ある条件のデータ(行)を抽出し、新しい名前の列をつける(mutate())

以下はデータセットOriginalにあるDayという列が3かつConstractという列のVectorというヤツを抽出し、それらに0という値を持つOrder_graphという新しい列を作り、その結果出上がったデータセットをNew_datasetとする、という意味。

R
New_dataset <- mutate(
  Original,
  Order_graph =
    case_when(
      Day == 3 & Constract == "Vector" ~ 0,
      Day == 3 & Constract == "M2"  ~ 1,
      Day == 7 & Constract == "Vector"  ~ 2,
      Day == 7 & Constract == "M2"  ~ 3,
      Day == 14 & Constract == "Vector"  ~ 4,
      Day == 14 & Constract == "M2"  ~ 5))   

類似の方法に以下のようにstr_detect()を使う方法がある。これはデータセットOriginalのTime_Drugという名前の変数(列)のデータにもし”DMSO”という文字が含まれていた場合に、DMSOという値を持つDrugという新しい変数(列)を作って、その結果できたデータセットをNew_datasetとする、という意味である。

R
New_dataset <- mutate(
  Original,
  Drug =
    case_when(
      str_detect(Time_Drug, "DMSO") == "TRUE" ~ "DMSO",
      str_detect(Time_Drug, "0.125uM") == "TRUE" ~ "0.125uM",
      str_detect(Time_Drug, "0.25uM") == "TRUE" ~ "0.25uM",
      str_detect(Time_Drug, "0.5uM") == "TRUE" ~ "0.5uM"
    ))

データフレームとtibble型のデータ(as.tibble()、data.frame())

c()で読み込んでcbind()なんかで作ったデータフレームは、dplyrでは扱えないので、as.tibble()でtibble型のデータに変換しなくてはならない。そうすれば、select()やfilter()などを適用できる。

R
Dataframe1 <- c("DMSO", "DMSO","DMSO","DMSO","DMSO", "Drug","Drug","Drug","Drug","Drug")
Dataframe2 <- c(1,1,1,1,1,3,3,3,3,3)
Dataframe3 <- c("Succeed","Succeed","Succeed","Succeed","Fail","Succeed","Fail","Succeed","Succeed","Succeed")
New_dataset <- cbind(Dataframe1, Dataframe2, Dataframe3)
New_dataset <- as.tibble(New_dataset)

逆にdataframeが必要なら、作ったtibble型のNew_datasetをas.dataframe()に入れれば良い。そのとき、一列目が番号になってたりするので、要注意である。

R
New_dataframe <- as.dataframe(New_dataset)