Посмотрите на Integer.java, если значение находится между -128 и 127, оно будет использовать кешированный пул, поэтому (Integer) 1 == (Integer) 1
пока (Integer) 222 != (Integer) 222
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Я бы захватил локальную среду,
xy <- data.frame(x=1:10,y=1:10)
plotfunc <- function(Data, YMul = 2){
.e <- environment()
ggplot(Data, aes(x = x, y = y*YMul), environment = .e) + geom_line()
}
plotfunc(xy)
Вы посмотрели на решение, данное @wch (W. Chang)?
https://github.com/hadley/ggplot2/issues/743
Я думаю, что он лучший
по существу похож на файл @baptiste, но включает ссылку на среду непосредственно в вызове ggplot
. Я сообщаю об этом здесь
g <- function() {
foo3 <- 4
ggplot(mtcars, aes(x = wt + foo3, y = mpg),
environment = environment()) +
geom_point()
}
g()
# Works
Вот альтернатива, которая позволяет передавать любое значение через аргумент YMul
, не добавляя его в файл ff.frame или в глобальную среду:
plotfunc <- function(Data, YMul = 2){
eval(substitute(
expr = {
ggplot(Data,aes(x=x,y=y*YMul)) + geom_line()
},
env = list(YMul=YMul)))
}
plotfunc(xy, YMul=100)
To посмотрите, как это работает, попробуйте следующую строку в отдельности:
substitute({ggplot(Data, aes(x=x, y=y*YMul))}, list(YMul=100))
browser()
внутри вызова aes()
, а после ввода sys.frames()
я получил список из 23 сред, ни один из которых (??), по-видимому, не дает прямого доступа к значению из YMul
. Хм.
– Josh O'Brien
18 May 2012 в 22:15
ggplot()
's aes
ожидает, что YMul
будет переменной в фрейме данных data
. Вместо этого попробуйте включить YMull
:
Благодаря @Justin: ggplot()
's aes
, похоже, сначала ищет YMul
в фрейме данных data
, а если не найден, то в глобальной среде. Мне нравится добавлять такие переменные в фрейм данных, как это следует, поскольку это имеет смысл для меня концептуально. Мне также не нужно беспокоиться об изменениях глобальных переменных, которые имеют неожиданные последствия для функций. Но все остальные ответы также верны. Итак, используйте то, что вам подходит.
require("ggplot2")
xy <- data.frame(x = 1:10, y = 1:10)
xy <- cbind(xy, YMul = 2)
ggplot(xy, aes(x = x, y = y * YMul)) + geom_line()
Или, если вам нужна функция в вашем примере:
plotfunc <- function(Data, YMul = 2)
{
ggplot(cbind(Data, YMul), aes(x = x, y = y * YMul)) + geom_line()
}
plotfunc(xy)
YMul
не обязательно должен быть частью data.frame. Он просто должен быть определен в области, где оценивается объект ggplot
, который является глобальным, а не функцией.
– Justin
18 May 2012 в 21:40
ggplot()
, похоже, сначала ищет YMul
в кадре данных, а затем, если не найден в глобальной среде, очевидно, пропуская аргументы функции. Я не нашел никакой информации о том, как ggplot()
ищет пространства имен, но опять же я не выглядел очень тяжело.
– jthetzel
18 May 2012 в 22:04
Если вы выполняете свой код вне функции, он работает. И если вы выполняете код внутри функции с YMul
, определенным глобально, он работает. Я не полностью понимаю внутреннюю работу ggplot
, но это работает ...
YMul <- 2
plotfunc <- function(Data){
ggplot(Data,aes(x=x,y=y*YMul))+geom_line()
}
plotfunc(xy)
Я использую ggplot2, и ваш пример, похоже, отлично работает с текущей версией.
Однако, легко найти варианты, которые все еще создают проблемы. Я сам был смущен подобным поведением, и именно так я нашел этот пост (верхний результат Google для «ggplot, как оценивать переменные при передаче»). Например, если мы переместим ggplot из plotfunc:
xy <- data.frame(x=1:10,y=1:10)
plotfunc <- function(Data,YMul=2){
geom_line(aes(x=x,y=y*YMul))
}
ggplot(xy)+plotfunc(xy)
# Error in eval(expr, envir, enclos) : object 'YMul' not found
В приведенном выше варианте «захват локальной среды» не является решением, потому что ggplot не вызывается из функции, и только ggplot имеет аргумент «environment =».
Но теперь существует семейство функций «aes_», «aes_string», «aes_q», которые похожи на «aes», но фиксируют локальные переменные. Если мы используем «aes_» в приведенном выше, мы все равно получаем ошибку, потому что теперь он не знает о «x». Но легко обращаться к данным напрямую, что решает проблему:
plotfunc <- function(Data,YMul=2){
geom_line(aes_(x=Data$x,y=Data$y*YMul))
}
ggplot(xy)+plotfunc(xy)
# works
y=1:10
из data.framexy
; (2) помещениеy<-1:10
в глобальную среду; и (3) поместитьy<-10:1
в тело функции до вызова ggplot. По сути, мое решение позволяет передавать выбранные аргументы, не изменяя при этом других правил. Ваш полностью изменяет поведение области видимостиggplot()
(вот почему мне это нравится). – Josh O'Brien 19 May 2012 в 17:06