京橋のバイオインフォマティシャンの日常

南国のビーチパラソルの下で、Rプログラムを打ってる日常を求めて、、Daily Life of Bioinformatician in Kyobashi of Osaka

【Rのジミ〜な小技シリーズ】変数で、データフレームに「任意の列名」を追加するTips

はじめに

pasteなどで連結して作成した文字列をもとにして、それらをデータフレームの列名にしたい。 そういうケースがよくあるのです。

食わず嫌い的に試して無かったけど、「えっ、これできるの?!」という感じなことが起こったようです・・・。 文字列の変数で、データフレームの列名を複数追加できることがわかったので、それをメモしておきます。 R歴 約10年、まだまだ奥が深い。

データフレームの列名を追加する

test <- data.frame(a=1:3, b=4:6, c="abc")
test
#  a b   c
#1 1 4 abc
#2 2 5 abc
#3 3 6 abc

#よくやる列追加のやり方
test$d <- 7:9
test
#  a b   c d
#1 1 4 abc 7
#2 2 5 abc 8
#3 3 6 abc 9

文字列の変数で、データフレームの列名を追加する

次に、文字列の変数で、データフレームの列名を追加してみます。

#任意の文字列を作成して、列名にする
col01 <- paste0("X", "01")
#[1] "X01"
  
test[,col01] <- NA
test
#  a b   c X01
#1 1 4 abc  NA
#2 2 5 abc  NA
#3 3 6 abc  NA

#複数の任意の文字列を作成して、列名にする
col02 <- paste0("X", c("02", "03", "04"))
col02
#[1] "X02" "X03" "X04"

test[,col02] <- NA
test
#  a b   c d X01 X02 X03 X04
#1 1 4 abc 7  NA  NA  NA  NA
#2 2 5 abc 8  NA  NA  NA  NA
#3 3 6 abc 9  NA  NA  NA  NA

上記の実行コードで、"X02" "X03" "X04"という列名が一気に追加されました。 なかなか秀逸と思います。

【Rのジミ〜な小技シリーズ】エクセルデータをクリップボードにコピーして、Rのread.table関数でデータフレームとして読み込むTips

エクセルデータをクリップボードにコピーしてR環境に読み込む

今までほぼやってなかったけど、さっき使ってみて思いの外、便利でよかったです。 今後はこれを使いたいと強いメッセージを込めて、これのみでメモっておきます。

まずは、Macでエクセルを起動します。 文字や数字が書かれた、エクセルの任意のセルを選択して、command + c でコピーします。

Rを起動して、以下のコマンドを打てば*1クリップボードからデータのインポートができます

ただ、以下のコード実行前に、command + c をもう一度打たないこと。 コピーしたデータがクリップボードから消えます。癖で打ってしまいそうになりますけど。。。

コピーしたセルがヘッダーを含む場合

Data <- read.table(pipe("pbpaste"), header=T, stringsAsFactors = F)
Data

# OR

Data <- read.table(pipe("pbpaste"), sep="\t", header=T, stringsAsFactors = F)
Data

コピーしたセルがヘッダーを含まない場合

Data <- read.table(pipe("pbpaste"), header=F, stringsAsFactors = F)
Data

# OR

Data <- read.table(pipe("pbpaste"), sep="\t", header=F, stringsAsFactors = F)
Data

追記(2020年6月10日): マークダウンなどでテーブル出力

実際に、クリップボードからR上にインポートして、 データフレームをBlog用のマークダウンなどでテーブル出力するのをやってみました。

エクセルで、以下の画像のようにセルをcommand + c でコピーしてみます。

エクセルを閉じずに、そのまま、以下のRコードを実行します。

if(!require("knitr")){install.packages("knitr")}; library(knitr)

Data <- read.table(pipe("pbpaste"), header=T, stringsAsFactors = F)

Data
#  A B  C  D
#1 1 2  3  4
#2 1 3  5  7
#3 2 5  8 11
#4 3 6  9 12
#5 4 7 10 13

#マークダウン出力
kable(Data, format = "markdown")

#|  A|  B|  C|  D|
#|--:|--:|--:|--:|
#|  1|  2|  3|  4|
#|  1|  3|  5|  7|
#|  2|  5|  8| 11|
#|  3|  6|  9| 12|
#|  4|  7| 10| 13|

#Latex出力
kable(Data, format = "latex")

#\begin{tabular}{r|r|r|r}
#\hline
#A & B & C & D\\
#\hline
#1 & 2 & 3 & 4\\
#\hline
#1 & 3 & 5 & 7\\
#\hline
#2 & 5 & 8 & 11\\
#\hline
#3 & 6 & 9 & 12\\
#\hline
#4 & 7 & 10 & 13\\
#\hline
#\end{tabular}

#Pandoc出力
kable(Data, format = "pandoc")

#  A    B    C    D
#---  ---  ---  ---
#  1    2    3    4
#  1    3    5    7
#  2    5    8   11
#  3    6    9   12
#  4    7   10   13

【Rのジミ〜な小技シリーズ】

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

skume.net

参考資料

http://marcoghislanzoni.com/blog/2013/10/27/import-data-r-mac-os-x-clipboard/marcoghislanzoni.com

riseki.php.xdomain.jp

*1:R4.0以降は大丈夫だが、 stringsAsFactors = F は念のためいれておくこと

grepコマンドで文字列処理をやってみた件【その2】検索語のヒット数カウントとか検索語の前後文字の抽出とか色々

はじめに

grepコマンドによる文字列処理をやってみた」の続編です。

以前扱えていなかった内容をやっていきたいです。

grepコマンドの基本については過去の記事を参照のこと。

skume.hatenablog.com

まずは、サンプルデータをダウンロードする

svn export  https://github.com/kumeS/Blog/trunk/grep_practice_02

cd ./grep_practice_02

# test.txtを使っていく。
cat test.txt

#abcde
#ABCDE
#
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#
#12345abcde67890fghij
#12345abcde67890fghij

検索語に一致した文字列のみを抜き出して出力する

grep -oを使うと、検索後と同じものが、ヒットした文字列として出力されます。

#'abc'で検索すると、5個ヒット
grep -o 'abc' test.txt
#abc
#abc
#abc
#abc
#abc

# -o を入れずに検索すると、'abc'を含む行数の4個でヒット
grep 'abc' test.txt
#abcdeabcde
#abcdefghijklmnopqrstuvwxyz
#12345abcde67890fghij
#12345abcde67890fghij

#'fghij'で検索すると、3個ヒット
grep -o 'fghij' test.txt
#fghij
#fghij
#fghij

大文字・小文字を区別せず、検索語に一致した文字列のみを抜き出して出力する

grep -o -iを使うと、大文字・小文字が区別されずに、ヒットした文字列が出力されます。

#'abc' or 'ABC'で検索され、8個ヒット
grep -o -i 'abc' test.txt
#abc
#abc
#ABC
#ABC
#abc
#ABC
#abc
#abc

# -i のみで検索すると、6個ヒット
grep -i 'abc' test.txt
#abcdeabcde
#ABCDEABCDE
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#12345abcde67890fghij
#12345abcde67890fghij

#'fghij' or 'FGHIJ' で検索され、4個ヒット
grep -o -i 'fghij' test.txt
#fghij
#FGHIJ
#fghij
#fghij

検索語に一致した文字列の数をカウントする【部分一致検索】

grep -ogrep -cを使うと、検索語に一致した文字列数が出力されます。

このとき注意することとしてコマンドを分けずに、grep -o -cにすると、行数カウントになります。

#'abc'で検索して、'abc'をカウントすると、5個ヒット
grep -o 'abc' test.txt | grep -c 'abc'
#5

# -o -c にすると、4個ヒットで、行数カウントになる
grep -o -c 'abc' test.txt
#4

#'fghij'で検索すると、3個ヒット
grep -o 'fghij' test.txt | grep -c 'fghij'
#3

検索語に一致した箇所の前後の行を出力する

grep -Cを使うと、前後の行(行数指定)を一緒に出力できます。

#前後1行を出力する
grep -C 1 'hijklmn' test.txt
#
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ

#前1行、後3行を出力する
grep  -B 1  -A 3 'hijklmn' test.txt
#123456
#abcdefghijklmnopqrstuvwxyz
#ABCDEFGHIJKLMNOPQRSTUVWXYZ
#
#12345abcde67890fghij

grep -B -Aを使うと、-Bで検索語前の行数、-Aで検索語後の行数を指定できます。

検索語に一致した箇所の前後の文字列を出力する

上記で、行レベルで出力する方法を紹介したが、 正規表現. (ピリオド)を使うと、前後の文字列も出力できます。

#検索語を抜き出して表示
grep -o 'efghijk' test.txt
#efghijk

#検索語の前4文字も含めて出力
grep -o '....efghijk' test.txt
#abcdefghijk

#検索語の後4文字も含めて出力
grep -o 'efghijk....' test.txt
#efghijklmno

#検索語の前4文字、後4文字も含めて出力
grep -o '....efghijk....' test.txt
#abcdefghijklmno

また、検索語を「変数」で指定することもできる。

TERMS=$"efghijk" ; grep -o "....$TERMS...." test.txt
#OR
TERMS=$'efghijk' ; grep -o "....$TERMS...." test.txt

#abcdefghijklmno

やってみると、'"の組み合わせが重要らしいです。

;は、複数文を繋げて書く文法である。

検索語を行番号付きで出力する

grep -nを使うと、行番号付きで出力されます。

#'abc'行を行番号付きで出力
grep -o -n 'abc' test.txt
#1:abc
#abc
#4:abc
#7:abc
#8:abc

grep -n 'abc' test.txt
#1:abcdeabcde
#4:abcdefghijklmnopqrstuvwxyz
#7:12345abcde67890fghij
#8:12345abcde67890fghij

#'fghij'行を行番号付きで出力
grep -o -n 'fghij' test.txt
#4:fghij
#7:fghij
#8:fghij

検索語の行番号のみを出力する

行番号のみを出力するには、sedとの組み合わせで行います。

#'abc'行を行番号のみ出力
grep -n 'abc' test.txt | sed -e 's/:.*//g'
#1
#4
#7
#8

#'fghij'行を行番号のみ出力
grep -n 'fghij' test.txt | sed -e 's/:.*//g'
#4
#7
#8

grepのエラーメッセージを消す

そのままではあまり使わないけど、プログラムを組むときには役に立つかもです。

#フォルダに実行するとエラーが出る
grep 'abcd' test
grep: test: Is a directory

grep -s 'abcd' test
#OR
grep --no-messages 'abcd' test
#エラーメッセージの非表示

まとめ

grepコマンドは結構役に立つので、一通り覚えておくと、 いろいろなテキストの前処理とかに使えそうです。

補足

正規表現のまとめ

正規表現 (Regular Expression)は、文字列のパターン・マッチングなどの表記法として使用する。

また、メタキャラクタとは、文字列のパターンを表す特殊な記号のことを指す。

メタキャラクタ そのメタキャラクタが意味すること
. 任意の一文字
* 前にある文字の0回以上の繰り返し
+ 前にある文字の1回以上の繰り返し
? 前にある文字の0回あるいは1回の意味
^ 指定した文字が文頭
$ 指定した文字が文末
[ ] 指定した複数の文字の中のいずれか
{ } 前にある文字の指定した回数の繰り返し
\w 英数文字またはアンダーバー。[a-zA-Z0-9_]と同等
\W \w 以外の文字
\d 数値文字。[0-9]と同等
\D 数値以外の文字。[^0-9]と同等
\s 空白文字
\S 空白以外の文字
\b ワードの先頭、あるいは末尾にマッチ
\B ワード内の文字列にマッチ
\A 文字列の最初にマッチ
\Z 文字列の最後にマッチ
\t タブ
\n 改行
\r キャリッジリターン

参考

www.wakuwakubank.com

webplus8.com

www.gadgety.net