・お題:data.frameの扱いをまだまだ覚えられないので、メモしておく。
・データは適当にcsvで用意した。
・とりあえず、tidyverseを読み込む。
> library(tidyverse)
・csvを読み込む。
> df0<-read.csv("20230416_0.csv")
> df0
・これでも良いといえば良いけれど、少し弄る。
> df0<-read.csv("20230416_0.csv",
+ stringsAsFactors = FALSE,
+ sep = ",",
+ na.strings = "")
> df0
・IDを行名にする。
> rownames(df0) <- df0$ID
> df0
・ID列を消す。
> df0$ID <- NULL
> df0
・Scoreが文字列として読み込まれているので、数字にする。
> df0$Score <- as.numeric(df0$Score)
Warning message:
NAs introduced by coercion
> df0
> df0 %>% str()
'data.frame': 6 obs. of 2 variables:
$ Name : chr "tanaka" "yamada" NA "sato" ...
$ Score: num 1 2 3 NA NA 6
・ちなみに、dfを纏めて数値にしたければ、df <- as.data.frame(sapply(df, as.numeric))みたいな書き方もOK。今回はNameが数値でないので、やらない。
・もうひとつdata.frameを読み込む。
> df1<-read.csv("20230416_1.csv",
+ stringsAsFactors = FALSE,
+ sep = ",",
+ na.strings = "",
+ row.names = 1#行名になる列が分かっているならこれでOK
+ )
> df1$Score <- as.numeric(df1$Score)
Warning message:
NAs introduced by coercion
>
> df1
・df1はdf0と列の順番が少し違う。しかも、df1にだけAgeがある。
・df0にdf1を縦にくっつける。
> df01<-bind_rows(df0,df1)
> df01
・なんだか良い感じにくっつけてくれた。
・もう一つ、データを読み込む。
> df2<-read.csv("20230416_2.csv",
+ stringsAsFactors = FALSE,
+ sep = ",",
+ na.strings = "",
+ row.names = 1
+ )
> df2
・df2は新たな列だけのデータフレームらしく、しかも行名がかなり歯抜けになっている。
・df01にdf2をくっつけるのに、bind_colsを使うとエラーが返ってくる。
> bind_cols(df01,df2)
Error in `bind_cols()`:
! Can't recycle `..1` (size 12) to match `..2` (size 6).
Run `rlang::last_trace()` to see where the error occurred.
・そこで、行名でくっつけるために、merge関数を使ってみるが、innner_joinっぽくなってうまくいかない。
> merge(df01, df2, by=0)
・なお、かくいうdplyrのjoinシリーズ(innner, outer, left, right)はbyに0を指定してもうまくいかない。
> inner_join(df01, df2, by=0)
Error in `inner_join()`:
! `by` must be a (named) character vector, list, `join_by()` result, or NULL, not the number
0.
Run `rlang::last_trace()` to see where the error occurred.
・そこで、無理やりやってみた。rownamesを列として作り直してくっつけてから消す。
> df012<-full_join(df01 %>% mutate(., ID = rownames(.)),
+ df2 %>% mutate(., ID = rownames(.)),
+ by="ID")
> df012
> rownames(df012)<-df012$ID
> df012 <- df012 %>% select(., -"ID")#selectにマイナスをつけると列を消せる
> df012
・一応できたが、センスがなさ過ぎて悶絶している。。
・merge関数のオプションでできるんじゃないかと思って調べてみると、確かにinnner_join以外のjoinをmergeで実行することもできるらしい。
> merge(df01,
+ df2,
+ by = 0,
+ all = TRUE)
・しかしながら、Row.namesという列ができてしまっており、問題が解決していない。。もっと探せば何とかなりそうな気もする。。
おわり。