dplyr 'object not found' 仅中位数
dplyr 'object not found' median only
这个问题难倒我了
我有以下数据框:
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))
和一个简单的 'summarize' 函数,它将列名作为变量,并且运行良好:
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
但是,如果我修改函数来获取中位数,它 returns 会出错:
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' 不接受列名作为传递的变量。我想我错过了一些非常基本的东西,当有人向我指出它时我会做一个面部手掌,但在此期间我觉得我正在失去理智。我很感激任何见解!
您的近端问题可能是 median
没有 ...
参数,而 mean
有(我不确定为什么 sd
有效。 .. 可能是方法与 ...
之间的交互?)
无论如何,IMO 处理此类问题的正确方法是使用 标准 评估(即 not 非标准评估,即使用 summarise_
而不是 summarise
,如 vignette("nse",package="dplyr")
):
所示
说明它是如何在全局环境中而不是在函数内部工作的,但我认为这无关紧要...
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)
这里唯一烦人的事情是由于某些原因 dplyr
找不到 median
除非我将其称为 stats::median
,这意味着我们必须更加努力地工作获得漂亮的列名。标准评估方法有点丑陋,但这是您为这种灵活性付出的代价。
将其嵌入函数中,我可能会在不同的地方中断 getStats
,即
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)
这使您可以更灵活地进行不同的分组...
这个问题难倒我了
我有以下数据框:
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))
和一个简单的 'summarize' 函数,它将列名作为变量,并且运行良好:
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
但是,如果我修改函数来获取中位数,它 returns 会出错:
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' 不接受列名作为传递的变量。我想我错过了一些非常基本的东西,当有人向我指出它时我会做一个面部手掌,但在此期间我觉得我正在失去理智。我很感激任何见解!
您的近端问题可能是 median
没有 ...
参数,而 mean
有(我不确定为什么 sd
有效。 .. 可能是方法与 ...
之间的交互?)
无论如何,IMO 处理此类问题的正确方法是使用 标准 评估(即 not 非标准评估,即使用 summarise_
而不是 summarise
,如 vignette("nse",package="dplyr")
):
说明它是如何在全局环境中而不是在函数内部工作的,但我认为这无关紧要...
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)
这里唯一烦人的事情是由于某些原因 dplyr
找不到 median
除非我将其称为 stats::median
,这意味着我们必须更加努力地工作获得漂亮的列名。标准评估方法有点丑陋,但这是您为这种灵活性付出的代价。
将其嵌入函数中,我可能会在不同的地方中断 getStats
,即
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)
这使您可以更灵活地进行不同的分组...