绘制内部函数:子集(df,id _ == ...)给出错误的绘图,df [df $ id _ == ...,]是对的

smc*_*mci 1 indexing evaluation r function subset

我有一个带有多个y系列的df,我想单独绘制,所以我写了一个fn,它选择一个特定的系列,分配给一个局部变量dat,然后绘制它.但是在fn中调用ggplot/geom_step并不像单个系列那样正确对待它.我不知道这可能是一个范围问题,因为如果dat不可见,ggplot肯定会失败?

从顶层环境执行时,您可以验证代码是否正确,但不在函数内部.这不是一个重复的问题.我理解这个问题(这是ggplot的一个反复出现的问题),但我已经阅读了所有其他答案; 这不是重复,他们不提供解决方案.geom_step无法像单个系列那样正确显示

set.seed(1234)
require(ggplot2)
require(scales)

N = 10
df <- data.frame(x = 1:N,
                 id_ = c(rep(20,N), rep(25,N), rep(33,N)),
                 y = c(runif(N, 1.2e6, 2.9e6), runif(N, 5.8e5, 8.9e5) ,runif(N, 2.4e5, 3.3e5)),
                 row.names=NULL)

plot_series <- function(id_, envir=environment()) {
  dat <- subset(df,id_==id_)
  p <- ggplot(data=dat, mapping=aes(x,y), color='red') + geom_step()
  # Unsuccessfully trying the approach from http://stackoverflow.com/questions/22287498/scoping-of-variables-in-aes-inside-a-function-in-ggplot
  p$plot_env <- envir
  plot(p)
  # Displays wrongly whether we do the plot here inside fn, or return the object to parent environment 
  return(p)
}

 # BAD: doesn't plot geom_step!
plot_series(20)

# GOOD! but what's causing the difference?
ggplot(data=subset(df,id_==20), mapping=aes(x,y), color='red') + geom_step()

#plot_series(25)
#plot_series(33)
Run Code Online (Sandbox Code Playgroud)

jor*_*ran 5

这很好用:

plot_series <- function(id_) {
    dat <- df[df$id_ == id_,]
    p <- ggplot(data=dat, mapping=aes(x,y), color='red') + geom_step()
    return(p)
}

print(plot_series(20))
Run Code Online (Sandbox Code Playgroud)

如果您只是单步执行原始函数debug,您将很快看到该subset行实际上根本没有对数据框进行子集化:它返回了所有行!

为什么?因为subset使用非标准评估,并且您对列名和函数参数使用了相同的名称.正如jlhoward在上面所说明的那样,仅仅使用不同的名称就可以(但可能不可取).

原因是subset首先使用数据框进行评估.因此,它在逻辑表达式中看到的只是id_ == id_在该数据帧中始终为真.

考虑它的一种方法是玩愚蠢(如计算机)并问自己什么时候提出条件id_ == id_你怎么知道每个符号究竟是指什么.这是不明确的,并subset做出一致的选择:使用数据框中的内容.