편집 : Hadley Wickham은 내가 틀린 것을 지적합니다. R CMD 점검이 경고가 아닌 참고를 던지고 있습니다. 혼란을 드려 죄송합니다. 내 감독이었다.
짧은 버전
R CMD check
ggplot2에서 합리적인 플롯 생성 구문 을 사용할 때 마다이 메모 를 던집니다.
no visible binding for global variable [variable name]
R CMD 검사가 왜 그렇게하는지 이해하지만, 그렇지 않으면 합리적인 구문의 전체 정 맥을 범죄 화하는 것으로 보입니다. 패키지를 전달 R CMD check
하고 CRAN에 입장하기 위해 어떤 단계를 수행해야하는지 잘 모르겠습니다 .
배경
Sascha Epskamp는 이전에 본질적으로 동일한 문제에 대해 게시했습니다 . 차이점은 subset()
맨 페이지 에서 대화 형으로 설계된 것 입니다.
내 경우에는, 문제는 이상하지 않습니다 subset()
만의 핵심 기능을 통해 ggplot2
: data =
인수.
이 노트를 생성하는 코드 예제
다음 은 플롯에 점을 추가하는 패키지 의 하위 기능 입니다 .
JitteredResponsesByContrast <- function (data) {
return(
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
)
}
R CMD check
이 코드를 파싱하면
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
R CMD 점검이 올바른 이유
점검은 기술적으로 정확합니다. x.values
과y.values
- 함수에서 로컬로 정의되지 않았습니다
JitteredResponsesByContrast()
x.values <- [something]
전 세계 또는 발신자 형태로 사전 정의되어 있지 않습니다 .
대신, 데이터 프레임 내에서 변수로 정의되어 이전에 정의되어 함수에 전달됩니다 JitteredResponsesByContrast()
.
ggplot2가 R CMD 확인을 어려워하는 이유
ggplot2는 data
인수 사용을 권장하는 것 같습니다 . 아마도 데이터 인수는이 코드가 실행되는 이유 일 것입니다
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
하지만 이 코드는 객체 찾을 수 없다는 오류가 발생합니다 :
library(ggplot2)
hwy # a variable in the mpg dataset
두 가지 해결 방법과 왜 내가 행복하지 않습니까?
NULL 아웃 전략
Matthew Dowle 은 문제가있는 변수를 먼저 NULL로 설정하는 것이 좋습니다 . 제 경우에는 다음과 같습니다.
JitteredResponsesByContrast <- function (data) {
x.values <- y.values <- NULL # Setting the variables to NULL first
return(
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
)
}
이 솔루션에 감사하지만 세 가지 이유로 싫어합니다.
- 적용 이외의 추가 목적은 없습니다
R CMD check
. - 의도를 반영하지 않습니다. 그것은
aes()
호출이 우리의 현재 NULL 변수를 볼 것이라는 기대를 불러 일으키고, 실제 목적을 모호하게합니다 (R CMD 검사는 달리 알지 못할 변수를 인식하게합니다) - 1과 2의 문제는 플롯 요소를 반환하는 함수를 작성할 때마다 혼란스러운 NULLing 문을 추가해야하기 때문에 곱하기
with () 전략
with()
더 큰 환경에서 문제의 변수를 찾을 수 있음을 명시 적으로 신호하는 데 사용할 수 있습니다. 제 경우에는 with()
다음과 같이 사용합니다.
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
이 솔루션이 작동합니다. 그러나이 솔루션은 내가 기대하는 방식으로 작동하지 않기 때문에 마음에 들지 않습니다. 경우 with()
실제로 변수는 위치로 통역을 가리키는의 문제를 해결 한 다음, 난 안 필요data =
인수를. 그러나 with()
그런 식으로 작동하지 않습니다.
library(ggplot2)
p <- ggplot()
p <- p + with(mpg, geom_point(aes(x = hwy, y = cty)))
p # will generate an error saying `hwy` is not found
다시 말하지만,이 솔루션에는 NULLing 전략과 비슷한 결함이 있다고 생각합니다.
- 여전히 모든 플롯 요소 함수를 거쳐
with()
호출 에서 논리를 래핑해야 합니다. with()
호출은 잘못된 것입니다. 나는 여전히data =
논쟁 을 제공 할 필요가있다 . 모든with()
일이 끝나고R CMD check
있습니다.
결론
내가 보는 방식에는 세 가지 옵션이 있습니다.
- 로비 CRAN은 “스퓨리어스”( CRAN 정책에 따라)라고 주장하여 메모를 무시하고 패키지를 제출할 때마다 수행합니다.
- 두 가지 바람직하지 않은 전략 중 하나를 사용하여 코드를 수정하십시오 (NULL 또는
with()
블록) - 정말 큰 소리로 문제가 사라지기를 바랍니다.
세 가지 중 어느 것도 나를 행복하게 만들지 않으며 사람들이 나 (및 ggplot2를 사용하려는 다른 패키지 개발자)가 무엇을 제안하는지 궁금합니다. 미리 감사드립니다. 나는 이것을 통해 당신의 독서를 정말로 감사합니다 🙂
답변
aes_string
대신에 사용해 보셨습니까 aes
? 시도하지는 않았지만 작동해야합니다.
aes_string(x = 'x.values', y = 'y.values')
답변
두 가지 해결책이 있습니다.
-
비표준 평가를 피하려면 코드를 다시 작성하십시오. ggplot2의 경우 이는 Harlan이 설명한대로
aes_string()
대신 사용함 을 의미합니다.aes()
-
globalVariables(c("x.values", "y.values"))
패키지의 최상위에 통화를 추가하십시오 .
CRAN에 제출할 때 약간 해키가 필요한 작업을 수행하더라도 패키지에 0 개의 메모가 있어야합니다. 이를 통해 CRAN의 삶이 편 해지고 쉬워집니다.
(이것에 대한 나의 최근 생각을 반영하기 위해 2014-12-31로 업데이트 됨)
답변
이 질문은 얼마 전에 요청 및 답변되었지만 버전 2.1.0 부터 메모를 해결할 수있는 다른 방법이 있습니다.aes_(x=~x.values,y=~y.values).
답변
만약
getRversion() >= "3.1.0"
패키지의 최상위 수준에서 통화를 추가 할 수 있습니다.
utils::suppressForeignCheck(c("x.values", "y.values"))
에서:
help("suppressForeignCheck")
답변
2019 년에이 문제를 해결하는 가장 좋은 방법 .data
은 rlang
패키지 의 접두사 를 사용하는 것 입니다. 이것은 치료에 R 지시 x.values
하고 y.values
A의 열로 data.frame
(이 정의되지 않은 변수에 대해 불평하지 않도록).
참고 : 데이터 입력에 존재하는 것으로 미리 정의 된 열 이름이있는 경우 가장 효과적입니다.
#' @importFrom rlang .data
my_func <- function(data) {
ggplot(data, aes(x = .data$x, y = .data$y))
}
답변
패키지 레벨 문서를 제공하는 파일에 다음 코드 행을 추가하십시오.
if(getRversion() >= "2.15.1") utils::globalVariables(c("."))
여기 예