R:round()可以找到对象,sprintf()不能,为什么?

时间:2012-05-21 08:32:15

标签: r ggplot2

我有一个函数,它使用ggplot2获取数据帧并从该数据帧中绘制多个列。 ggplot2中的aes()函数采用label参数,我想使用sprintf格式化该参数 - 这是我之前在其他代码中做过很多次的事情。当我将格式字符串传递给sprintf(在本例中为“%1.1f”)时,它表示“找不到对象”。如果我使用round()函数并将参数传递给该函数,它可以毫无问题地找到它。格式()也是如此。显然只有sprintf()无法看到对象。

起初我认为这是一个懒惰的评估问题,因为调用函数而不是使用内联代码,但在我传递给sprintf的格式字符串上使用force()并不能解决问题。我可以解决这个问题,但我想知道为什么会这样。当然,我可能忽略了一些微不足道的事情。

Q值。为什么sprintf()找不到字符串对象?

代码如下(编辑和修剪以获得更少的示例)

require(gdata)
require(ggplot2)
require(scales)
require(gridExtra)
require(lubridate)
require(plyr)
require(reshape)

set.seed(12345)
# Create dummy time series data with year and month
monthsback <- 64
startdate <- as.Date(paste(year(now()),month(now()),"1",sep = "-")) - months(monthsback)
mydf <- data.frame(mydate = seq(as.Date(startdate), by = "month", length.out = monthsback), myvalue5 = runif(monthsback, min = 200, max = 300))
mydf$year <- as.numeric(format(as.Date(mydf$mydate), format="%Y"))
mydf$month <- as.numeric(format(as.Date(mydf$mydate), format="%m"))

getchart_highlight_value <- function(
                          plotdf,
                          digits_used = 1
                          )
{
    force(digits_used)
    #p <- ggplot(data = plotdf, aes(x = month(mydate, label = TRUE), y = year(mydate), fill = myvalue5, label = round(myvalue5, digits_used))) +
    # note that the line below using sprintf() does not work, whereas the line above using round() is fine
    p <- ggplot(data = plotdf, aes(x = month(mydate, label = TRUE), y = year(mydate), fill = myvalue5, label = sprintf(paste("%1.",digits_used,"f", sep = ""), myvalue5))) +
      scale_x_date(labels = date_format("%Y"), breaks = date_breaks("years")) +
      scale_y_reverse(breaks = 2007:2012, labels = 2007:2012, expand = c(0,0)) +
      geom_tile() + geom_text(size = 4, colour = "black") +
      scale_fill_gradient2(low = "blue", high = "red", limits = c(min(plotdf$myvalue5), max(plotdf$myvalue5)), midpoint = median(plotdf$myvalue5)) +
      scale_x_discrete(expand = c(0,0)) +
      opts(panel.grid.major = theme_blank()) +
      opts(panel.background = theme_rect(fill = "transparent", colour = NA)) +
      png(filename = "c:/sprintf_test.png", width = 700, height = 300, units = "px", res = NA)
      print(p)
      dev.off()
}

getchart_highlight_value (plotdf <- mydf,
                          digits_used <- 1)

2 个答案:

答案 0 :(得分:4)

这是一个最小的例子

require(ggplot2)

getchart_highlight_value <- function(df)
{
    fmt <- "%1.1f"
    ggplot(df, aes(x, x, label=sprintf(fmt, lbl))) + geom_tile()
}

df <- data.frame(x = 1:5, lbl = runif(5))
getchart_highlight_value (df)

失败了

> getchart_highlight_value (df)
Error in sprintf(fmt, lbl) : object 'fmt' not found

如果我在全球环境中创建fmt那么一切都很好;也许这解释了'有时它有用'/'它对我有用'以上评论。

> sessionInfo()
R version 2.15.0 Patched (2012-05-01 r59304)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=C                 LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_0.9.1

loaded via a namespace (and not attached):
 [1] colorspace_1.1-1   dichromat_1.2-4    digest_0.5.2       grid_2.15.0       
 [5] labeling_0.1       MASS_7.3-18        memoise_0.1        munsell_0.3       
 [9] plyr_1.7.1         proto_0.3-9.2      RColorBrewer_1.0-5 reshape2_1.2.1    
[13] scales_0.2.1       stringr_0.6       

答案 1 :(得分:4)

使用Martin的最小示例(这是一个最小示例,另请参阅this question),您可以通过指定ggplot()应该使用的环境来使代码工作。为此,请在environment函数中指定参数ggplot(),例如:

require(ggplot2)

getchart_highlight_value <- function(df)
{
  fmt <- "%1.1f"
  ggplot(df, aes(x, x, label=sprintf(fmt, lbl)),
         environment = environment()) + 

  geom_tile(bg="white") + 
  geom_text(size = 4, colour = "black")
}

df <- data.frame(x = 1:5, lbl = runif(5))
getchart_highlight_value (df)

函数environment()返回当前(本地)环境,该环境是函数getchart_highlight_value()创建的环境。如果您未指定此内容,ggplot()将查看全局环境,并且未定义变量fmt

与懒惰评估无关,与选择合适的环境无关。

上面的代码产生了以下情节:

enter image description here