Rの機能をコピペで便利に使う

cliprパッケージを使ってカジュアルにRの機能を利用する。
clipr
R
Published

August 26, 2024

Rで使うことのできる便利な関数をもっと気軽に使いたいと思うことはないだろうか? ここでは気軽にRの関数を利用するための便利なパッケージcliprを紹介する。

Read and Write from the System Clipboard

Simple utility functions to read from and write to the Windows, OS X, and X11 clipboards.

https://matthewlincoln.net/clipr

cliprパッケージを使うと、適当にデータをどこかからコピーしてRの関数に渡し、 Rの関数で処理した上でまた別のところに貼り付ける、という作業が簡単にできる様になる。

基本的には、Rによるデータ処理はソースファイルにコードを残しておき、 作業を再現可能にしておくことが望ましい。 しかし、インターネット上のWebページなどからコピーした文字列をちょっと整形するといった、 コードとして残すほどではないが手作業でやるには面倒な作業を、 コンソール上でさくっと終わらせたい時に、cliprパッケージは非常に便利である。

cliprパッケージ

コピーアンドペーストを行うときは、OSのclipboardという領域とデータをやり取りする。 Rのcliprパッケージを使うと、このclipboardとRとの間でデータをやり取りすることができる。 基本的な使用方法は、

  1. clipr::read_clip()でclipboardからデータをRのオブジェクトとして受け取る
  2. clipr::write_clip()にRのオブジェクトを渡し、clipboardに書き込む

のたった2つである。

cliprパッケージの利用例

例1)文章からの遺伝子IDの抽出

実際にcliprがどのようなシーンで活用できるか考えてみよう。 例えば、論文の文章中に以下のような遺伝子のIDがリストアップされているとしよう。 この文字列から、一つ一つの遺伝子のIDを取り出したいときにどうしたら良いだろうか?

In Arabidopsis thaliana, the genes AT2G18790, AT5G10140, AT1G09570, AT1G64280, AT1G66340, AT2G32950, AT4G39400, AT5G03280, AT4G08920, AT4G26080 and AT5G11260 are critical for various physiological processes.

cliprパッケージを使えばRで簡単にこれを行うことができる。 まずは上の文字列をコピーしよう。 コピーした文字列はclipboardからclipr::read_clip()で読みだすことができる。

clipr::read_clip()
#> [1] "In Arabidopsis thaliana, the genes AT2G18790, AT5G10140, AT1G09570, AT1G64280, AT1G66340, AT2G32950, AT4G39400, AT5G03280, AT4G08920, AT4G26080 and AT5G11260 are critical for various physiological processes."

clipboardから文字列として読み出すことができれば、 あとはstringrパッケージなどのRの文字列処理関数を使って簡単に操作することができる。 またRにはパイプ演算子があるので、処理を左から右に流れる様に書くことができる。

# AGIコードを正規表現で抽出
clipr::read_clip() |> stringr::str_extract_all("AT.G\\d{5}") |> unlist()
#>  [1] "AT2G18790" "AT5G10140" "AT1G09570" "AT1G64280" "AT1G66340" "AT2G32950"
#>  [7] "AT4G39400" "AT5G03280" "AT4G08920" "AT4G26080" "AT5G11260"

# 第一染色体上の遺伝子のAGIコードを正規表現で抽出
clipr::read_clip() |> stringr::str_extract_all("AT1G\\d{5}") |> unlist()
#> [1] "AT1G09570" "AT1G64280" "AT1G66340"

以下の様に、表記揺れがある場合はどうしたら良いだろうか? 各遺伝子IDのアルファベットに大文字と小文字が混ざっていて一貫性がない。

AT2G18790, AT5G10140, At1G09570, At1G64280, At1G66340, At2g32950, At4g39400, At5g03280, at4g08920, at4g26080, at5g11260

このような表記揺れ・ミスは人間が書く以上どうしても防ぎきれないと思うが、 stringrパッケージを使えばこの様な場合にも容易に対処できる。

# 前の正規表現だと最初の2つしか抽出できない
clipr::read_clip() |>
    stringr::str_extract_all("AT.G\\d{5}") |>
    unlist()
#> [1] "AT2G18790" "AT5G10140"

# 大文字小文字を区別しないような正規表現にする
clipr::read_clip() |>
    stringr::str_extract_all("(?i)AT.G\\d{5}") |>
    unlist()
#>  [1] "AT2G18790" "AT5G10140" "At1G09570" "At1G64280" "At1G66340" "At2g32950"
#>  [7] "At4g39400" "At5g03280" "at4g08920" "at4g26080" "at5g11260"

# いったん全部大文字にしてから抽出
clipr::read_clip() |>
    stringr::str_to_upper() |>
    stringr::str_extract_all("AT.G\\d{5}") |>
    unlist()
#>  [1] "AT2G18790" "AT5G10140" "AT1G09570" "AT1G64280" "AT1G66340" "AT2G32950"
#>  [7] "AT4G39400" "AT5G03280" "AT4G08920" "AT4G26080" "AT5G11260"
Tip

cliprパッケージでコピーした文字列からのデータの抽出などの操作が容易に(カジュアルに)行える。

例2)塩基配列の操作

cliprパッケージを使うことで、DNA配列などの簡単な操作を行うこともできる。 以下はある遺伝子の翻訳領域(coding sequence, CDS)のDNA配列を、FASTA形式にしたものである。

>ACT2_AT3G18780.2_CDS
ATGGCTGAGGCTGATGATATTCAACCAATCGTGTGTGACAATGGTACCGGTATGGTGAAG
GCTGGATTTGCAGGAGATGATGCTCCCAGGGCTGTTTTTCCCAGTGTTGTTGGTAGGCCA
AGACATCATGGTGTCATGGTTGGGATGAACCAGAAGGATGCATATGTTGGTGATGAAGCA
CAATCCAAGAGAGGTATTCTTACCTTGAAGTATCCTATTGAGCATGGTGTTGTTAGCAAC
TGGGATGATATGGAAAAGATCTGGCATCACACTTTCTACAATGAGCTTCGTATTGCTCCT
GAAGAGCACCCTGTTCTTCTTACCGAGGCTCCTCTTAACCCAAAGGCCAACAGAGAGAAG
ATGACTCAAATCATGTTTGAGACCTTTAACTCTCCCGCTATGTATGTCGCCATCCAAGCT
GTTCTCTCCTTGTACGCCAGTGGTCGTACAACCGGTATTGTGCTGGATTCTGGTGATGGT
GTGTCTCACACTGTGCCAATCTACGAGGGTTTCTCTCTTCCTCATGCCATCCTCCGTCTT
GACCTTGCTGGACGTGACCTTACTGATTACCTCATGAAGATCCTTACAGAGAGAGGTTAC
ATGTTCACCACAACAGCAGAGCGGGAAATTGTAAGAGACATCAAGGAGAAGCTCTCCTTT
GTTGCTGTTGACTACGAGCAGGAGATGGAAACCTCAAAGACCAGCTCTTCCATCGAGAAG
AACTATGAATTACCCGATGGGCAAGTCATCACGATTGGTGCTGAGAGATTCAGATGCCCA
GAAGTCTTGTTCCAGCCCTCGTTTGTGGGAATGGAAGCTGCTGGAATCCACGAGACAACC
TATAACTCAATCATGAAGTGTGATGTGGATATCAGGAAGGATCTGTACGGTAACATTGTG
CTCAGTGGTGGAACCACTATGTTCTCAGGTATCGCTGACCGTATGAGCAAAGAAATCACA
GCACTTGCACCAAGCAGCATGAAGATTAAGGTCGTTGCACCACCTGAAAGGAAGTACAGT
GTCTGGATCGGTGGTTCCATTCTTGCTTCCCTCAGCACATTCCAGCAGATGTGGATCTCC
AAGGCCGAGTATGATGAGGCAGGTCCAGGAATCGTTCACAGAAAATGTTTCTAA

このDNA配列部分をマウスで選択してコピーし、clipr::read_clip()で読み込むと改行ごとに区切られた文字列ベクトルが得られる。

clipr::read_clip() |>
    stringr::str_view()
 [1] │ ATGGCTGAGGCTGATGATATTCAACCAATCGTGTGTGACAATGGTACCGGTATGGTGAAG
 [2] │ GCTGGATTTGCAGGAGATGATGCTCCCAGGGCTGTTTTTCCCAGTGTTGTTGGTAGGCCA
 [3] │ AGACATCATGGTGTCATGGTTGGGATGAACCAGAAGGATGCATATGTTGGTGATGAAGCA
 [4] │ CAATCCAAGAGAGGTATTCTTACCTTGAAGTATCCTATTGAGCATGGTGTTGTTAGCAAC
 [5] │ TGGGATGATATGGAAAAGATCTGGCATCACACTTTCTACAATGAGCTTCGTATTGCTCCT
 [6] │ GAAGAGCACCCTGTTCTTCTTACCGAGGCTCCTCTTAACCCAAAGGCCAACAGAGAGAAG
 [7] │ ATGACTCAAATCATGTTTGAGACCTTTAACTCTCCCGCTATGTATGTCGCCATCCAAGCT
 [8] │ GTTCTCTCCTTGTACGCCAGTGGTCGTACAACCGGTATTGTGCTGGATTCTGGTGATGGT
 [9] │ GTGTCTCACACTGTGCCAATCTACGAGGGTTTCTCTCTTCCTCATGCCATCCTCCGTCTT
[10] │ GACCTTGCTGGACGTGACCTTACTGATTACCTCATGAAGATCCTTACAGAGAGAGGTTAC
[11] │ ATGTTCACCACAACAGCAGAGCGGGAAATTGTAAGAGACATCAAGGAGAAGCTCTCCTTT
[12] │ GTTGCTGTTGACTACGAGCAGGAGATGGAAACCTCAAAGACCAGCTCTTCCATCGAGAAG
[13] │ AACTATGAATTACCCGATGGGCAAGTCATCACGATTGGTGCTGAGAGATTCAGATGCCCA
[14] │ GAAGTCTTGTTCCAGCCCTCGTTTGTGGGAATGGAAGCTGCTGGAATCCACGAGACAACC
[15] │ TATAACTCAATCATGAAGTGTGATGTGGATATCAGGAAGGATCTGTACGGTAACATTGTG
[16] │ CTCAGTGGTGGAACCACTATGTTCTCAGGTATCGCTGACCGTATGAGCAAAGAAATCACA
[17] │ GCACTTGCACCAAGCAGCATGAAGATTAAGGTCGTTGCACCACCTGAAAGGAAGTACAGT
[18] │ GTCTGGATCGGTGGTTCCATTCTTGCTTCCCTCAGCACATTCCAGCAGATGTGGATCTCC
[19] │ AAGGCCGAGTATGATGAGGCAGGTCCAGGAATCGTTCACAGAAAATGTTTCTAA

一つの塩基配列にしたいので、以下の様に末端の空白文字を消す処理と、 文字列を結合して一つにする処理を行うと、目的の文字列データが得られる。

clipr::read_clip() |>
    stringr::str_squish() |>
    stringr::str_flatten() |>
    stringr::str_view()
[1] │ ATGGCTGAGGCTGATGATATTCAACCAATCGTGTGTGACAATGGTACCGGTATGGTGAAGGCTGGATTTGCAGGAGATGATGCTCCCAGGGCTGTTTTTCCCAGTGTTGTTGGTAGGCCAAGACATCATGGTGTCATGGTTGGGATGAACCAGAAGGATGCATATGTTGGTGATGAAGCACAATCCAAGAGAGGTATTCTTACCTTGAAGTATCCTATTGAGCATGGTGTTGTTAGCAACTGGGATGATATGGAAAAGATCTGGCATCACACTTTCTACAATGAGCTTCGTATTGCTCCTGAAGAGCACCCTGTTCTTCTTACCGAGGCTCCTCTTAACCCAAAGGCCAACAGAGAGAAGATGACTCAAATCATGTTTGAGACCTTTAACTCTCCCGCTATGTATGTCGCCATCCAAGCTGTTCTCTCCTTGTACGCCAGTGGTCGTACAACCGGTATTGTGCTGGATTCTGGTGATGGTGTGTCTCACACTGTGCCAATCTACGAGGGTTTCTCTCTTCCTCATGCCATCCTCCGTCTTGACCTTGCTGGACGTGACCTTACTGATTACCTCATGAAGATCCTTACAGAGAGAGGTTACATGTTCACCACAACAGCAGAGCGGGAAATTGTAAGAGACATCAAGGAGAAGCTCTCCTTTGTTGCTGTTGACTACGAGCAGGAGATGGAAACCTCAAAGACCAGCTCTTCCATCGAGAAGAACTATGAATTACCCGATGGGCAAGTCATCACGATTGGTGCTGAGAGATTCAGATGCCCAGAAGTCTTGTTCCAGCCCTCGTTTGTGGGAATGGAAGCTGCTGGAATCCACGAGACAACCTATAACTCAATCATGAAGTGTGATGTGGATATCAGGAAGGATCTGTACGGTAACATTGTGCTCAGTGGTGGAACCACTATGTTCTCAGGTATCGCTGACCGTATGAGCAAAGAAATCACAGCACTTGCACCAAGCAGCATGAAGATTAAGGTCGTTGCACCACCTGAAAGGAAGTACAGTGTCTGGATCGGTGGTTCCATTCTTGCTTCCCTCAGCACATTCCAGCAGATGTGGATCTCCAAGGCCGAGTATGATGAGGCAGGTCCAGGAATCGTTCACAGAAAATGTTTCTAA

(ここまで書くならソースコードに書いた方がいいと思うが、) 一応さくっとCDSに含まれる各コドンの頻度をグラフ化することもできる。

Code
library(ggplot2)
clipr::read_clip() |>
    stringr::str_squish() |>
    stringr::str_flatten() |>
    stringr::str_extract_all("...") |>
    unlist() |>
    tibble::tibble(codon = _) |>
    dplyr::summarise(.by = codon, count = dplyr::n()) |>
    dplyr::arrange(desc(count)) |>
    dplyr::mutate(
        codon = forcats::fct_inorder(codon),
        AA = Biostrings::GENETIC_CODE[codon]
    ) |>
    ggplot(aes(codon, count)) +
    geom_col(aes(fill = AA)) +
    facet_grid(cols = vars(AA), scales = "free_x", space = "free_x") +
    theme_minimal() +
    theme(
       axis.text.x = element_text(angle = 90),
       panel.grid.minor = element_blank(),
       panel.grid.major.x = element_blank(),
       legend.position = "none"
    ) +
    scale_y_continuous(expand = expansion(c(0, .1)))

生物学的配列データを取り扱うBiostringsパッケージを利用することで、 コピーしたDNA配列を逆相補鎖にしたり、アミノ酸配列に翻訳したりすることができる。

# 文字列を`Biostrings`パッケージを使ってDNA配列として読み込む
clipr::read_clip() |>
    stringr::str_squish() |>
    stringr::str_flatten() |>
    Biostrings::DNAString() -> cds
cds
#> 1134-letter DNAString object
#> seq: ATGGCTGAGGCTGATGATATTCAACCAATCGTGTGT...GCAGGTCCAGGAATCGTTCACAGAAAATGTTTCTAA

# 逆相補鎖
cds |> Biostrings::reverseComplement()
#> 1134-letter DNAString object
#> seq: TTAGAAACATTTTCTGTGAACGATTCCTGGACCTGC...ACACACGATTGGTTGAATATCATCAGCCTCAGCCAT

# 翻訳
cds |> Biostrings::translate()
#> 378-letter AAString object
#> seq: MAEADDIQPIVCDNGTGMVKAGFAGDDAPRAVFPSV...IGGSILASLSTFQQMWISKAEYDEAGPGIVHRKCF*

操作したデータはclipr::write_clip()でclipboardに書き出し、任意の場所でペーストすることができる。

# CDSをコピーして、その末端のストップコドンを除去してから、翻訳したアミノ酸配列を書き戻す
clipr::read_clip() |>
  paste0(collapse = "") |>
  stringr::str_remove("(TAG|TGA|TAA)$") |>
  Biostrings::DNAString() |>
  Biostrings::translate() |>
  as.character() |>
  clipr::write_clip()

貼り付けるとこんな感じになる。(見やすさのために40字ごとに折り返した。)

MAEADDIQPIVCDNGTGMVKAGFAGDDAPRAVFPSVVGRP
RHHGVMVGMNQKDAYVGDEAQSKRGILTLKYPIEHGVVSN
WDDMEKIWHHTFYNELRIAPEEHPVLLTEAPLNPKANREK
MTQIMFETFNSPAMYVAIQAVLSLYASGRTTGIVLDSGDG
VSHTVPIYEGFSLPHAILRLDLAGRDLTDYLMKILTERGY
MFTTTAEREIVRDIKEKLSFVAVDYEQEMETSKTSSSIEK
NYELPDGQVITIGAERFRCPEVLFQPSFVGMEAAGIHETT
YNSIMKCDVDIRKDLYGNIVLSGGTTMFSGIADRMSKEIT
ALAPSSMKIKVVAPPERKYSVWIGGSILASLSTFQQMWIS
KAEYDEAGPGIVHRKCF

例3)表の読み込み

cliprパッケージでコピーした表をdata.frame(あるいはtibble)として読み込むこともできる。 以下の様な表があるとする。

Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa

上の表をコピーして、data.frameとして読み込むには以下の様にすれば良い。

clipr::read_clip()で読み込んだ文字列を、改行文字(\n)で一つの文字列に結合し、 readr::read_tsv()に渡す。

clipr::read_clip() |>
    paste(collapse = "\n") |>
    readr::read_tsv(show_col_types = FALSE)
# A tibble: 6 × 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <chr>  
1          5.1         3.5          1.4         0.2 setosa 
2          4.9         3            1.4         0.2 setosa 
3          4.7         3.2          1.3         0.2 setosa 
4          4.6         3.1          1.5         0.2 setosa 
5          5           3.6          1.4         0.2 setosa 
6          5.4         3.9          1.7         0.4 setosa 

実は、clipr::read_clip() |> paste(collapse = "\n")の部分を一つの関数で行う、 readr::clipboard()という関数もある。

readr::clipboard() |> readr::read_tsv(show_col_types = FALSE)
# A tibble: 6 × 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <chr>  
1          5.1         3.5          1.4         0.2 setosa 
2          4.9         3            1.4         0.2 setosa 
3          4.7         3.2          1.3         0.2 setosa 
4          4.6         3.1          1.5         0.2 setosa 
5          5           3.6          1.4         0.2 setosa 
6          5.4         3.9          1.7         0.4 setosa 

また、読み込みはtibbleではなくdata.frameになるが一つの関数で表を読み込むことができる、 clipr::read_clip_tbl()という関数もある。

clipr::read_clip_tbl()
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

Excelなどからコピーしたセルも、上記の手法でdata.frameとして読み込むことができるはずである。

Caution

一点、注意すべき点はPDFやウェブサイトにある表はコピーしても、 これらのようなやり方で簡単に変換できる形式にならない場合が往々にしてあるということである。 その場合はいったんExcelなどに貼り付けて、地道に手作業で修正する必要がある。

dput()関数

ここまではcliprパッケージでclipboardから読み込んだデータを、 書き捨てのコードでデータ処理する例を示してきた。 一方で、あとで同じような解析をしたいと思って、 cliprパッケージを使ったコードをソースファイルに残しておいても、 コピーする元のデータがなければコードを残す意味がなくなってしまう。 つまり、clipr::read_clip()で読み込んだデータをあとで使いたい場合は、 データを再利用可能な形に変換しておく必要がある。

一つのやり方は、データをファイルに書き出す方法である。 例えば、data.frameならばcsvファイルなどに書き出せば良いだろう。

別のやり方として、データを直接Rのコードとしてソースファイルなどに残す方法がある。 これはdput()関数を使うことで達成できる。 dput()にRのオブジェクトを渡すことで、そのRオブジェクトを作るためのコードを表示することができる。 あとは、表示された文字列をコピーしてソースファイルに貼り付ければ、 データをコードの形で保存することができる。

1:10 |> dput()
#> 1:10

LETTERS[1:10] |> dput()
#> c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")

clipr::read_clip_tbl()で読み込まれたdata.framedput()でコードの形式に変換できる。 ただし少し見にくい。

clipr::read_clip_tbl() |> dput()
#> structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6, 5, 5.4), 
#>     Sepal.Width = c(3.5, 3, 3.2, 3.1, 3.6, 3.9), Petal.Length = c(1.4, 
#>     1.4, 1.3, 1.5, 1.4, 1.7), Petal.Width = c(0.2, 0.2, 0.2, 
#>     0.2, 0.2, 0.4), Species = c("setosa", "setosa", "setosa", 
#>     "setosa", "setosa", "setosa")), class = "data.frame", row.names = c(NA, 
#> -6L))

まとめ

cliprを使うことで、ソースコードにコードを書かずともコンソールに直接書き捨てのコードを書いて、 手軽にRの関数などを利用することができる。

上手く活用することで、Rをより便利に使うことができようになると思う。

Sessioninfo

sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Asia/Tokyo
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_3.5.1

loaded via a namespace (and not attached):
 [1] utf8_1.2.4              generics_0.1.3          bitops_1.0-7           
 [4] stringi_1.8.4           hms_1.1.3               digest_0.6.34          
 [7] magrittr_2.0.3          evaluate_0.24.0         grid_4.3.2             
[10] fastmap_1.1.1           jsonlite_1.8.8          GenomeInfoDb_1.38.5    
[13] fansi_1.0.6             scales_1.3.0            Biostrings_2.70.2      
[16] cli_3.6.3               rlang_1.1.4             crayon_1.5.2           
[19] XVector_0.42.0          bit64_4.0.5             munsell_0.5.1          
[22] withr_3.0.0             yaml_2.3.9              parallel_4.3.2         
[25] tools_4.3.2             tzdb_0.4.0              dplyr_1.1.4            
[28] colorspace_2.1-1        GenomeInfoDbData_1.2.11 forcats_1.0.0          
[31] BiocGenerics_0.48.1     vctrs_0.6.5             R6_2.5.1               
[34] stats4_4.3.2            lifecycle_1.0.4         zlibbioc_1.48.0        
[37] stringr_1.5.1           bit_4.0.5               S4Vectors_0.40.2       
[40] htmlwidgets_1.6.4       IRanges_2.36.0          vroom_1.6.5            
[43] pkgconfig_2.0.3         clipr_0.8.0             pillar_1.9.0           
[46] gtable_0.3.5            glue_1.7.0              xfun_0.46              
[49] tibble_3.2.1            tidyselect_1.2.1        knitr_1.48             
[52] farver_2.1.2            htmltools_0.5.7         rmarkdown_2.25         
[55] labeling_0.4.3          readr_2.1.5             compiler_4.3.2         
[58] RCurl_1.98-1.14