機略戦記

Maneuver warfare

[R] 文字列が複数格納されたvectorを結合して一つの文字列にしたい

結論

> string_vector <- c('abc', 'def', 'ghi')
> Reduce(function(x, y){ paste(x,  y) }, string_vector)
[1] "abc def ghi"

こうすれば行ける。
もっとシンプルな方法は無いものか…

背景

ある変数のclassをチェックして、想定外の値だったらstop()させるような処理が書きたい。

stop()させた時、エラーメッセージとしてチェックした変数のclassを表示したい。

この時、class()の戻り値は文字列のvectorである可能性がある。

これをいい感じに表示したかった。

  • classを複数持っている例:
> class(data.table())
[1] "data.table" "data.frame"

R あるdata.tableが指定したカラムを備えているか判定したい。ただし指定したカラム以外のカラムがくっついていてもTRUEを返させたい。

結論

# 期待するカラム(の名前)
expect_column_names <- c('V1', 'V2') 

# 判定したいテーブルが持っているカラム。
# 「V3は別にマストで存在していて欲しい訳ではないがあっても問題ない」という条件で判定したい。
column_names <- names(data.table(V1=1, V2=2, V3=3)) 

all(expect_column_names %in% column_names)
# TRUE

説明

あるdata.tableが指定したカラムを備えているか判定したい。ただし指定したカラム以外のカラムがくっついていてもTRUEを返させたい。

言い換えると、「期待するカラム名data.tableが持つカラム名の部分集合か判定したい」という事である。

上記でその判定ができる。

R で data.tableに変数で指定した名前の列を追加したい

結論

  • eval以外のいい方法が見つからなかった。
sample_data_table <- data.table(V1=1, V2=2)
new_column_name <- 'new_column'

expr <- parse(text = paste(new_column_name, ":= V1+V2"))
sample_data_table[, eval(expr)]

## Checking the result
print(sample_data_table)
#    V1 V2 new_column
# 1:  1  2          3

説明

  • new_column_nameで指定したカラム名のカラムを追加している。
  • 内容は、V1+V2
  • 静的に書いた場合こういうコードになる。
    • sample_data_table[, new_column := V1+V2]
    • new_columnの部分を変数で指定するためにevalしている。

MacでRを実行している時、処理が終わったら通知を行う方法

結論

# 処理
system("osascript -e 'display notification \"done.\"'")

結果

f:id:Shinya_131:20151104214013p:plain

説明

  • AppleScriptから通知を行う事ができる。
  • osascriptを使うことで、AppleScriptのコードをシェルからevalできる ← これでshellから通知を行える
  • sysytem()を使うことで、shellのコードをRからevalできる。

関連

shinya131-note.hatenablog.jp

R6でAll elements of public, private, and active must be namedと言われた時チェックすべき点

R6パッケージを使って作ったクラスについて、以下のエラーが出る事がある。

 R6::R6Class("XxxxXxxx", public = list(initialize = function(xxxxx) { でエラー: 
  All elements of public, private, and active must be named. 

R6で定義しているメソッドについて

  • mehotd_name = function() {}では無く、
  • mehotd_name <- function() {}を使うとこのようなエラーが起きるようだ。
XxxxXxxx <- R6::R6Class('XxxxXxxx',
  public = list(
    initialize = function(xxx) {
    },
    hoge <- function(xxx) { # ここで起きてる。
    }
  ),
  private = list(
    xxx = NA
  )
)

rubyでcall stack参照するメソッドがなんだっけ

結論

callerだった。

使用例:

$ pry
[1] pry(main)> caller
=> ["/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:355:in `eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:355:in `evaluate_ruby'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:323:in `handle_line'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `catch'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `block in eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `catch'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `eval'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:77:in `block in repl'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `loop'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `repl'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `block in start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:61:in `call'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:61:in `__with_ownership'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/input_lock.rb:79:in `with_ownership'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/repl.rb:15:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/pry_class.rb:169:in `start'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:219:in `block in <top (required)>'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `call'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `block in parse_options'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `each'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `parse_options'",
 "/Users/hoge/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/pry-0.10.3/bin/pry:16:in `<top (required)>'",
 "/Users/hoge/.rbenv/versions/2.2.3/bin/pry:23:in `load'",
 "/Users/hoge/.rbenv/versions/2.2.3/bin/pry:23:in `<main>'"]

よもやま

ところでcallerって、メソッドだっけ? それとも特殊な変数か何か? というのが気になった。
このような疑問が湧いた時、defined?を使うと、コンソール上でこれを確認できる。

[9] pry(main)> defined? caller
=> "method"

ところでところで、defined?には調べたいもののシンボルや文字列では無く、調べたい物を直接渡す。

[11] pry(main)> defined? caller
=> "method"

おなじくメタ情報を取得する#methodの場合は、シンボルで引数として受け取ってる。

[13] pry(main)> method(:caller)
=> #<Method: Object(Kernel)#caller>

defined?はなんで構文上意味がある物を直接受け取る事ができるんだろう。
defined?はメソッドなんだろうか?
defined? defined?としてみたが syntax errorになってしまった。

すくなくともメソッドでは無い。

method(:defined?)
NameError: undefined method `defined?' for class `Object'
from (pry):17:in `method'