Rでweb APIを使わずに5行で顔認識する
こんな話がある。 私は大人気ないのでRなら5行、いや実質3行だよとか言ってしまう。 以下はopencvパッケージのサンプルコードそのまま。
install.package("opencv") # インストール library(opencv) unconf <- ocv_read('https://github.com/dichika/ojisan/raw/master/teramonagi_001.jpg') #画像読み込み faces <- ocv_face(unconf) #顔認識 ocv_write(faces, 'faces.jpg') #出力
まあOpenCV使えばどんな言語でもだいたい顔認識できるんじゃねえのって話。
化合物データの前処理をやりたい
化合物データの前処理をやる必要が出てきた。
ということである程度用語とかツールのイメージを把握しておきたい。
知ってる限りでとりあえず列挙。知りたいことを整理する。
1.化合物データのフォーマット確認:まずはSDFとSMILESを覚えておけば良いか。
2.すぐ使えそうなデータの確認:Pubchemとか?
Rだとこの辺のパッケージを使ってデータを取ってくる。cdkrはCDKのラッパ。rJava依存なので怖い。
https://github.com/ropensci/webchem
3.RDKitを使って作れる特徴量の確認:フィンガープリントとか?
https://qiita.com/muuu4649/items/7ef341f57bbea3988517
あーこれを読みながら一通り手を動かすのが一番手っ取り早いな。
CSVファイルを読み込む際「nullが埋め込まれている」とエラーが出た時はUTF-16LEを疑う
Windowsのもと作られたCSVファイルを読み込む際、CP932を指定しようというのは定石だが、それでもうまくいかないことがある。
エラーメッセージを読むと「nullが埋め込まれている」とある。
意味がわからない。
「nullが埋め込まれている」だから大方「R embedded null」あたりでググればなんかヒントあるだろと思って検索すると以下のSOがトップで出てくる。
解決策を見ると、こういうファイルは大抵Windowsで作られたUTF-16LEのファイルだからそれを試してみろとある。
実際に試してみるとうまくいった。
ちなみにreadrパッケージのread.csv()でlocale = locale(encoding = "UTF-16LE")と指定してもうまくいかない。
ここに対応するのはなかなか大問題らしく未対応のようである。
いまどきの固定長データはread_fwf()を用いて読み込む
こんな感じのデータがあったとする。
library(readr) fwf_sample <- readr_example("fwf-sample.txt") cat(read_lines(fwf_sample)) John Smith WA 418-Y11-4111 Mary Hartford CA 319-Z19-4341 Evan Nolan IL 219-532-c301
いわゆる固定長データであり、バイト数を指定して読み込むことになる。 Rだともともとread.fwf()という関数が用意されている。 https://dichika.hateblo.jp/entry/20120406/1333683931
が、いちいちバイト数を指定するのは面倒である。とにかく楽をしたい。データの読み込みなんぞで力を使いたくない。 空白のカラムからよしなにバイト数を推定して読み込んで欲しい。 こういう時はreadrパッケージのread_fwf()を利用する。
# 空白のカラムからよしなにバイト数を指定してもらうパターン read_fwf(fwf_sample, fwf_empty(fwf_sample, col_names = c("first", "last", "state", "ssn")))
もちろんバイト数を指定するパターンも利用できるし、色々な指定法がある。
# バイト数を指定するパターン read_fwf(fwf_sample, fwf_widths(c(20, 10, 12), c("name", "state", "ssn"))) # 上記を各列名と紐づけて指定するパターン read_fwf(fwf_sample, fwf_cols(name = 20, state = 10, ssn = 12)) # 開始位置と終了位置を指定するパターン # この場合、nameの開始位置は1 終了位置は20、ssnの開始位置は30 終了位置は42 read_fwf(fwf_sample, fwf_positions(c(1, 30), c(20, 42), c("name", "ssn"))) # 上記を各列名と紐づけて指定するパターン read_fwf(fwf_sample, fwf_cols(name = c(1, 20), ssn = c(30, 42)))
いかがでしたか?
数字をアルファベットに変換したい時はchartr()を使う
数字をアルファベットに変換したい、もしくはその逆でアルファベットを数字に変換したいというときがたまにあります。
例えば、11, 12, 13 をAA, AB, ACに変換したいという時です。
こういう時はRではchartr()を利用します。
chartr("123456789", "ABCDEFGHI", 11:13) [1] "AA" "AB" "AC"
第一・第二引数にそれぞれ対応表を与えて、最後に変換したいベクトルを与えるだけです。
0も加えて以下のような指定が楽かも。
chartr(paste(collapse="", 0:9), paste(collapse="", letters[1:10]), 11:13) [1] "bb" "bc" "bd"
(追記)
0-9 みたいな範囲指定使えますよ。
— kos59125 (@kos59125) 2019年2月18日
確かにこっちの方が楽。
chartr("0-9", "a-z", 11:13) [1] "bb" "bc" "bd"
いかがでしたか?
折れ線グラフで各系列にラベルをつける際はgghighlightを用いるのが楽なんじゃなかろうか
こういうデータがあるとする。
library(dplyr) library(ggplot2) library(gghighlight) ChickWeight_diet <- ChickWeight %>% group_by(Diet, Time) %>% summarise(weight = mean(weight)) > ChickWeight_diet # A tibble: 48 x 3 # Groups: Diet [?] Diet Time weight <fct> <dbl> <dbl> 1 1 0 41.4 2 1 2 47.2 3 1 4 56.5 4 1 6 66.8 5 1 8 79.7 6 1 10 93.1 7 1 12 109. 8 1 14 123. 9 1 16 145. 10 1 18 159. # … with 38 more rows
折れ線グラフで各系列にラベルをつけたい。
いろいろやり方はあるが、gghighlightパッケージを用いるのが一番楽な印象。
gghighlight()の条件設定で全て該当するような条件を設定するのがポイント。
なお、筆者の環境はMacなので、日本語が文字化けするためlabel_paramsでMacの日本語フォントを指定している。
ggplot(ChickWeight_diet, aes(Time, weight, color=Diet)) + geom_line() + gghighlight(max(weight)>0, label_params = list(family = "HiraKakuPro-W3"))
追記(2019/2/17) 開発者よりコメントいただき、条件設定は不要とのこと。
なるほど、こういう使い方もあるんですね! ちなみにmax(weight)>0みたいなダミーのpredicateはなくても大丈夫です。 https://t.co/n8hFDuPP2r
— Hiroaki Yutani (@yutannihilation) 2019年2月16日
いかがでしたか?
Rで時刻の差をとるときは単位を指定する癖をつける(もしくはlubridate::time_length()を用いる)
時刻を入れたデータフレームがあるとする。
> smp <- data.frame(now=Sys.time(), then=Sys.time()-60) > smp now then 1 2019-02-09 10:30:15 2019-02-09 10:29:15
で、時刻の差を計算すると、そこに単位も含まれてくる。
> smp$diff <- with(smp, now - then) > smp now then diff 1 2019-02-09 10:30:15 2019-02-09 10:29:15 59.99999 secs
これは煩わしいので、as.numeric()で数値に変える。
> smp$diff <- with(smp, as.numeric(now - then)) > smp now then diff 1 2019-02-09 10:30:15 2019-02-09 10:29:15 59.99999
一見問題ないように見えるが、次のような時に困る。
> smp <- data.frame(now=Sys.time(), then=Sys.time()-3600) > smp$diff <- with(smp, as.numeric(now - then)) > smp now then diff 1 2019-02-09 10:38:55 2019-02-09 09:38:55 60
これは時刻の差分を計算する時に呼び出されるdifftime()の引数unitsがデフォルトではautoとなっていることに起因する。 したがっていつも同じ単位で結果が欲しいときは、演算子ではなくdifftime()を用いて、unitsを指定するとよい。
> smp$diff <- with(smp, as.numeric(difftime(now, then, units = "secs"))) > smp now then diff 1 2019-02-09 10:45:00 2019-02-09 09:45:00 3600
もしくはlubridateパッケージでtime_length()を用いるという手もある。 こちらはデフォルトがsecsになっている。 なお、time_length()はIntervalクラスの値を求めるので、interval()してから渡してやる必要がある点に注意。
> smp$diff <- with(smp, time_length(interval(then, now))) > smp now then diff 1 2019-02-09 10:45:00 2019-02-09 09:45:00 3600
interval()の演算子として%--%も用意されているので、パイプを使いたいときはこちらもあり。
> smp <- smp %>% + mutate(diff = then %--% now %>% time_length()) > smp now then diff 1 2019-02-09 10:49:53 2019-02-09 09:49:53 3600
いかがでしたか????