web-dev-qa-db-ja.com

dplyr'rename '標準評価関数が期待どおりに機能していませんか?

更新:この投稿に関する以下のコメントから、これは期待どおりに機能しており、ここで説明した問題はありません。

以下は、dplyrのrename_を使用したおもちゃの例です。以下の2番目の例を使用して、列名を元の名前に戻すことができると期待していましたが、関数の引数の評価ルールが原因で、思ったとおりに機能しなくなっていると思います。元のplyrパッケージrename関数を使用する(および基本パッケージnames関数を使用する)簡単な回避策がありますが、これに対するdplyrソリューションが不足しているように感じます。

以下に示すような回避策がありますが、2番目の例のdplyrソリューションが期待どおりに機能すること、または期待どおりに機能することを期待すべきでない理由の説明の両方を歓迎します。

ありがとう、マット

編集:これを機能させるためにrename_を使用して以下の例を追加しましたが、複雑です。ハドリーが以下で言及しているバグが修正されれば、これは彼が以下に示すように機能すると思います。それまでは、私の厄介な方法はありますが、標準のplyrメソッドを使用する方がおそらく良いでしょう。また、完全性など、最後にベースRテクニックを追加しました。

library(plyr)
library(dplyr)

# dataframe to operate on
dat <- data_frame(a=1, b=1)

# identifier with string of column name in dat
x <- "a"


# Renaming using standard evaluation this way works
dat %>%
    rename_("new" = x)
# Source: local data frame [1 x 2]
# 
#   new b
# 1   1 1


# But changing it back does not
# I expect "a" to be the name, not the identifier x
dat %>%
    rename_("new" = x) %>%
    rename_(x = "new")
# Source: local data frame [1 x 2]
# 
#   x b
# 1 1 1


# This works, but seems really awkward...
dat %>%
    rename_("newname" = x) %>%
    do(do.call(rename_, setNames(list(., "newname"), c(".data", x))))

# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1


# This works fine
dat %>%
    rename_("new" = x) %>%
    plyr::rename(c("new" = x))
# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1


# Base R way
datrn <- dat %>%
    rename_("newname" = x)
names(datrn)[names(datrn) == "newname"] = x
datrn
# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1
15
mpettis

これを苦痛にするいくつかのことがあります:

  1. c(x = "new")c("x" = "new")と同じであり、c(new = x)の反対ではありません。

  2. setNames(x, "new")を使用して必要なベクトルを作成できますが、...

  3. .dots引数をrename_に追加するのを忘れた(バグレポート https://github.com/hadley/dplyr/issues/708 )ので、追加できません:

    rename_(dat, .dots = setNames(x, "new"))
    

    代わりに、do.callを使用する必要があります。

    do.call(rename_, c(list(quote(dat)), list(setNames(x, "new"))))
    
15
hadley

私のRstudioでは、次のように定義しています。

x <- 'myname'
dat <- data.frame(yes=1, no=2)

変数名をyesからmynameに変更したい

それは機能しません:

rename_(dat, .dots = setNames(x, "yes"))

しかし、これは機能します:

rename_(dat, .dots = setNames("yes", x))

rename_(dat, .dots = setNames("yes", paste(x) ))
2
Gianna