2016-11-25 11 views
2

この問題は私を困惑させました。dplyr 'オブジェクトが見つかりません'中央値のみ

私は、次のデータフレームを持っている:

library(dplyr) 

# approximation of data frame 
x <- data.frame(doy = sample(c(seq(200, 300)), 20, replace = T), 
       year = sample(c("2000", "2005"), 20, replace = T), 
       phase = sample(c("pre", "post"), 20, replace = T)) 

と、単純な変数としてカラム名を取り込み機能「をまとめたもの」と、うまく動作します。しかし

getStats <- function(df, col) { 
     col <- as.name(col) 
     df %>% 
     group_by(year, phase) %>% 
     summarize(n = sum(!is.na(col)), 
        mean = mean(col, na.rm = T), 
        sd = sd(col, na.rm = T), 
        se = sd/sqrt(n)) 
} 

> getStats(x, "doy") 
Source: local data frame [4 x 6] 
Groups: year [?] 

    year phase  n mean  sd  se 
    <fctr> <fctr> <int> <dbl> <dbl> <dbl> 
1 2000 post  8 248.625 30.42526 10.75695 
2 2000 pre  2 290.000 14.14214 10.00000 
3 2005 post  5 231.400 32.86031 14.69558 
4 2005 pre  5 274.200 29.79429 13.32441 

、I場合関数を修正して中央値を取得すると、エラーが返されます。

getStats <- function(df, col) { 
     col <- as.name(col) 
     df %>% 
     group_by(year, phase) %>% 
     summarize(n = sum(!is.na(col)), 
        mean = mean(col, na.rm = T), 
        med = median(col, na.rm = T), # new line 
        sd = sd(col, na.rm = T), 
        se = sd/sqrt(n)) 
    } 

> getStats(x, "doy") 

Error in median (doy, na.rm = TRUE): object "doy" not found 

名前と位置は変更されますが、すべて同じ結果が得られます。 'median'は、渡された変数として列名を受け入れません。私は何かを欠いていると思うので、基本的に私は誰かが私にそれを指摘するときに顔の手のひらをするだろうが、その間に私は私の正気を失っているように感じる。私は洞察力に感謝します!いずれにおいても

答えて

3

あなたの近位の問題はmeanはないながらmedianは、...引数を持っていないのかもしれ(sdは多分...メソッドと...の間の相互作用を働いている私はなぜわからない?)

場合は、この種の問題を処理するために、IMO正しい方法は、(vignette("nse",package="dplyr")に示されるように、すなわち、ない非標準の評価は、すなわち、summariseではなくsummarise_を使用)標準評価を使用することです:

これはグローバルな環境ではなく、関数内で動作しますが、私はそれは問題ではないはずだと思うの様子を示す

...

col <- "doy" 
funs <- c("n","mean","stats::median","sd","se") 
## put together function calls 
dots <- c(sprintf("sum(!is.na(%s))",col), 
     sprintf("%s(%s,na.rm=TRUE)",funs[2:4],col), 
     "sd/sqrt(n)") 
names(dots) <- gsub("^.*::","",funs) ## ugh 
dots 
##        n       mean 
##    "sum(!is.na(doy))"   "mean(doy,na.rm=TRUE)" 
##      median        sd 
## "stats::median(doy,na.rm=TRUE)"   "sd(doy,na.rm=TRUE)" 
##        se 
##     "sd/sqrt(n)" 

x %>% 
    group_by(year, phase) %>% 
    summarise_(.dots=dots) 

ここでの唯一の迷惑な事は、何らかの理由でdplyrmedianを見つけることができないということです私がそれをstats::medianと呼ぶ場合を除き、良い列名を得るためにもっと少しずつ努力する必要があります。標準的な評価方法はやや醜いですが、それはこの種の柔軟性のために支払う価格です。機能でこれを埋め込む

、私はおそらく私が不合理で応援しています

+0

...つまり

getStats <- function(data,col) { ## if you want to pass a string argument instead, remove ## the next line col <- deparse(substitute(col)) funs <- c("n","mean","stats::median","sd","se") dots <- c(sprintf("sum(!is.na(%s))",col), sprintf("%s(%s,na.rm=TRUE)",funs[2:4],col), "sd/sqrt(n)") names(dots) <- gsub("^.*::","",funs) ## ugh summarise_(data,.dots=dots) } x %>% group_by(year,phase) %>% getStats(doy) 

これはあなたに別のグループ化を行うにはより多くの柔軟性を提供し、別の場所でgetStatsをオフに破ります私自身がこの解決法を思いついたとは思っていませんでした。雷が速く、徹底的で、役立つ答えをありがとう。同じ問題を扱う人にとって、 'deparse'行を削除すると、上記の関数は文字列変数を扱うことができることに注意してください。すなわち、 'getStats(data、colName)'、 'colName < - " doy "' – Jaywalker

関連する問題