Open13

【R】 小技メモ

Ryota ChijimatsuRyota Chijimatsu

lapplyでリストの名前属性も使いたい時

デモデータ
hoge <- vector("list", length=3)
names(hoge) <- c("a","b","c")

seq(list)でリスト番号ベクトル取り出し、lapplyに使用する。

seq()関数にリストを入れるとリストの長さ分の連番が作られる。

seq(hoge)

[1] 1 2 3

この連番ベクトルを使ってlapply()。xにはリストの要素番号が渡される。function内でリストのx番目のdataやリストの名前属性のx番目を取り出せば良い。

hoge <- lapply(seq(hoge), function(x){
    name <- names(hoge)[x]
    data <- hoge[[x]]
})

名前属性のベクトル

hoge <- lapply(names(hoge), function(name){
    data <- hoge[[name]]
})
Ryota ChijimatsuRyota Chijimatsu

空のオブジェクト作成

空のベクトル

hoge <- NULL

特定の型を指定した空ベクトル

foo <- as.numeric()

長さを指定して空ベクトル作成

bar <- character(length = 10)



空のmatrix, data.frame

matrix(nrow = 5,ncol = 10)

入れる値を指定
matrix(data = "", nrow = 5,ncol = 10)

空のdata.frame
data.frame(matrix(data = "", nrow = 5,ncol = 10))


空のリスト

hoge <- list()

長さを指定して空のリスト作成

foo <- vector(mode = "list", length = 10)

長さを指定した作った空のリストではリストの要素に名前を付けることができる。

Ryota ChijimatsuRyota Chijimatsu

1行で名前付きベクトル作成

data.frameから1列だけ抜き出したベクトルにはdata.frameの行名が残らない。

setNames()機能を使えば1行で名前付きベクトルが作れる。

setNames(object = mtcars$mpg, nm = rownames(mtcars))

Ryota ChijimatsuRyota Chijimatsu

pattern matchの時の正規表現例

デモ用ベクトル

a <- "MUT: A159P; AMP. BBB_C/D\\-E"

特定の記号をXXXに変換する例を考える。

コロンや半角スペース、アンダーバーなどなどの記号をパターンマッチさせる際は特に何も意識しなくてよい。

gsub(pattern = ":", replacement = "XXX", x = a)
gsub(pattern = ";", replacement = "XXX", x = a)
gsub(pattern = " ", replacement = "XXX", x = a)
gsub(pattern = "_", replacement = "XXX", x = a)
gsub(pattern = "/", replacement = "XXX", x = a)
gsub(pattern = "-", replacement = "XXX", x = a)

ピリオドは任意の1文字を意味する。ベクトルの1文字ずつがXXXに変換される。

gsub(pattern = ".", replacement = "XXX", x = a)

ちなみにピリオドを2つにすると、2文字ずつがXXXに変換される。3つにすると3文字ずつXXXに変換される。.{回数}のようにしてもよい。

gsub(pattern = "..", replacement = "XXX", a)
gsub(pattern = "...", replacement = "XXX", a)

ピリオドは1つだけで使用すると、全文字がヒットしてしまうが、他の文字と組み合わせると任意の文字数を変換できる。

# コロンと次の1文字
gsub(pattern = ":.", replacement = "XXX", a)

# BBBとその後ろ3文字
gsub(pattern = ";...", replacement = "XXX", a)  

# 先頭から2文字
gsub(pattern = "^..", replacement = "XXX", a)

# 後ろから4文字
gsub(pattern = "....$", replacement = "XXX", a)

先頭を示す^と末尾を示す$を単独で使うと、文字が置換されずに挿入される。

gsub(pattern = "^", replacement = "XXX", a)
gsub(pattern = "$", replacement = "XXX", a)

ピリオドを沢山打てば長い文字をヒットさせられるが、ある個所以前/以後をヒットさせるにはピリオドとアスタリスクを組み合わせるとよい。

# :の前は何文字でもヒットする。
gsub(pattern = ".*:", replacement = "XXX", a)  

# BBBの後ろは何文字でもヒットする。
gsub(pattern = "BBB.*", replacement = "XXX", a) 

正規表現をエスケープ

ピリオドを正規表現として使わずにピリオドを変換したい場合はバックスラッシュを2つつける。\\.

gsub(pattern = "\\.", replacement = "XXX", x = a)

バックスラッシュを文字として扱いたいときも、バックスラッシュをつけるのだが、挙動がわかりにくいので、あまり使わないようにする方が無難

Ryota ChijimatsuRyota Chijimatsu

Objectのメモリサイズを調べる

object.size(obj)
Mb単位に直して表示
format(object.size(obj), units = "Mb")
Ryota ChijimatsuRyota Chijimatsu

repのtimes引数、each引数を使って全組み合わせ作成

繰り返しを行うrep()関数のtimes=引数では、ベクトルを指定数繰り返す。

rep(LETTERS[1:5], times = 3)

一方、each=引数では、1要素を指定数繰り返して、2要素目の繰り返しを行う。

rep(LETTERS[1:5], each = 3)

これをcbind()で列方向に繋げれば、全組み合わせを作ることができる。

cbind(rep(LETTERS[1:5], times = 3),rep(LETTERS[1:5], each = 3))

さらに1列目と2列目の要素が同じものを除くと1つ vs その他全ての組み合わせを作成できる。

hoge <- cbind(rep(LETTERS[1:5], times = 3),rep(LETTERS[1:5], each = 3))
hoge[hoge[,1] != hoge[,2], ]

expand.grid()関数でもよい。

expand.grid(LETTERS[0:3], letters[0:3])

Ryota ChijimatsuRyota Chijimatsu

dputを使えば、Rコードで使える出力の形で返してくれる。

ベクトルの出力を別の関数にコピペして使いたい時に便利

Ryota ChijimatsuRyota Chijimatsu

table()の結果をdata.frameにするとき

table(diamonds$cut, diamonds$color)

data.frameに渡すだけで頻度の列が作れる

data.frame(table(diamonds$cut, diamonds$color))

table()の出力形状を維持したければ、as.data.frame.matrixに渡す

as.data.frame.matrix(table(diamonds$cut, diamonds$color))

Ryota ChijimatsuRyota Chijimatsu

重複があるものには1つ目から連番をつける。

make.names()だと重複した要素の登場2回目に.1が付いてしまうので、重複要素の1つ目から連番をつけるように自作。

gene <- unique(gene_symbol)

for(i in gene){
  n <- sum(gene_symbol %in% i)
  if(n > 1){
    count <- seq(n)
    gene_symbol[gene_symbol %in% i] <- paste(i, count, sep = "_")
  }
}
Ryota ChijimatsuRyota Chijimatsu

エラーメッセージが日本語だと、エラーの検索がヒットしにくいので英語でエラーメッセージを表示させたい。

Sys.setenv("LANG" = "en")

日本語に戻す

 Sys.setenv("LANG" = "ja")
Ryota ChijimatsuRyota Chijimatsu

処理待ち中にConsoleを使えるようにする

重たい処理を待っている間が勿体ないので、バックグラウンドで実行させる。
エラーメッセージなどが途中で出ないので、単純な処理だけにしておいた方が無難かも。

でもRStudioではダメっぽい。

library(future)
plan(multisession)

fut <- future({
  saveRDS(atlas, "Object.rds")
})

Objectが巨大だと次エラーが出た。

This exceeds the maximum allowed size of 500.00 MiB

options(future.globals.maxSize = 110 * 1024^10)で適当に大きい値を入れたら行けた。

処理が終わったのかどうかはコマンド打ってみないわからない。

# 処理の状態を確認
resolved(fut)

エラーメッセージ等もコマンドで取り出す

# 結果を取得(エラーがあれば、ここで表示されます)
value(fut)
Ryota ChijimatsuRyota Chijimatsu

Rでsedコマンドみたいなパターンキャプター

sub()関数でできる。pattern=引数でキャプターしたい箇所を丸括弧で囲む。replacement=引数で"\\1"のように呼び出せる。

x <- "aaa123__/bbb"

# _より前をキャプチャー
sub(pattern = "^(.*)_.*",replacement = "\\1", x)

# _より前とbbbの箇所をキャプチャー。キャプチャー箇所を入れ替えて返す
sub(pattern = "^(.*)_.*(bbb)",replacement = "\\2\\1", x)



1つのキャプターに複数候補を入れる。

y <- c("Group_A 1", "Group_A 2", "Group_A 3",
       "Group_B 1", "Group_B 2", "Group_B 2",
       "Group_B_2 1", "Group_B_2 2", "Group_B_2 3")

sub(pattern = "^(Group_A|Group_B).*",replacement = "\\1", y)