ggplot2 구문이 합리적 일 때 "전역 변수에 대한 가시적 바인딩 없음"메모를 R CMD 검사로 처리하려면 어떻게해야합니까?


180

편집 : Hadley Wickham은 내가 틀린 것을 지적합니다. R CMD 점검이 경고가 아닌 참고를 던지고 있습니다. 혼란을 드려 죄송합니다. 내 감독이었다.

짧은 버전

R CMD checkggplot2에서 합리적인 플롯 생성 구문 을 사용할 때 마다이 메모 를 던집니다.

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.valuesy.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))
    )
  )
}

이 솔루션에 감사하지만 세 가지 이유로 싫어합니다.

  1. 적용 이외의 추가 목적은 없습니다 R CMD check.
  2. 의도를 반영하지 않습니다. 그것은 aes()호출이 우리의 현재 NULL 변수를 볼 것이라는 기대를 불러 일으키고, 실제 목적을 모호하게합니다 (R CMD 검사는 달리 알지 못할 변수를 인식하게합니다)
  3. 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 전략과 비슷한 결함이 있다고 생각합니다.

  1. 여전히 모든 플롯 요소 함수를 거쳐 with()호출 에서 논리를 래핑해야 합니다.
  2. with()호출은 잘못된 것입니다. 나는 여전히 data =논쟁 을 제공 할 필요가있다 . 모든 with()일이 끝나고 R CMD check있습니다.

결론

내가 보는 방식에는 세 가지 옵션이 있습니다.

  1. 로비 CRAN은 "스퓨리어스"( CRAN 정책에 따라)라고 주장하여 메모를 무시하고 패키지를 제출할 때마다 수행합니다.
  2. 두 가지 바람직하지 않은 전략 중 하나를 사용하여 코드를 수정하십시오 (NULL 또는 with()블록)
  3. 정말 큰 소리로 문제가 사라지기를 바랍니다.

세 가지 중 어느 것도 나를 행복하게 만들지 않으며 사람들이 나 (및 ggplot2를 사용하려는 다른 패키지 개발자)가 무엇을 제안하는지 궁금합니다. 미리 감사드립니다. 나는 이것을 통해 당신의 독서를 정말로 감사합니다 :-)


20
나는 # 1과 # 3을 좋아한다.
Ben Bolker

8
@ BenBolker도 저의 기술입니다.
hadley 2012

6
네 번째 옵션이 있습니다 : 'R CMD check'수정 및 r-devel에 패치를 제출하여 고려하십시오. 나는 당신이 어느 것이 가짜인지 아닌지를 감지하는 것이 매우 어렵다는 것을 알게 될 것입니다. 누군가 그렇게하기 위해 코드 조각을 생각
해냈다면

6
다른 전략을 사용하는 것입니다aes_string
hadley

2
이것은에 문제가 될 것으로 보인다 transformsubset도 (확실하지 않은 100 %,하지만 의미가 있습니다).
BrodieG

답변:


45

aes_string대신에 사용해 보셨습니까 aes? 시도하지는 않았지만 작동해야합니다.

aes_string(x = 'x.values', y = 'y.values')

4
단지 경고 : aes동안 수행 aes_string위치 매개 변수를 정의하지 않습니다 xy.
topchef

6
또 다른 경고. aes_string을 사용하면 x 및 y 값을 조작하는 함수를 사용할 수 없습니다. 변환 y를 기록하고 싶다면 aes_string (x = 'x.values', y = 'log (y.values)')는 작동하지 않습니다. 나는 이런 종류의 변형을 많이 사용하므로 aes_string은 항상 옵션이 아닙니다.
Dr. Mike

아마도이 답변 (및 가장 많은 표를 얻은 답변)은 aes_string"이 기능은 모두 사용되지 않습니다. 단정 한 평가 관용구를 대신 사용하십시오. (ggplot2 버전 3.2.1). 아마도이 rlang::.data음표를 침묵시키는 가장 좋은 후보가 될 것입니다 .
Vandenman

86

두 가지 해결책이 있습니다.

  • 비표준 평가를 피하려면 코드를 다시 작성하십시오. ggplot2의 경우 이는 Harlan이 설명한대로 aes_string()대신 사용함 을 의미합니다.aes()

  • globalVariables(c("x.values", "y.values"))패키지의 최상위에 통화를 추가하십시오 .

CRAN에 제출할 때 약간 해키가 필요한 작업을 수행하더라도 패키지에 0 개의 메모가 있어야합니다. 이를 통해 CRAN의 삶이 편 해지고 쉬워집니다.

(이것에 대한 나의 최근 생각을 반영하기 위해 2014-12-31로 업데이트 됨)


26
globalVariables끔찍한 해킹이며 절대 사용하지 않습니다.
hadley

10
가치있는 일로,이 노트 때문에 패키지 제출이 거부되었으며 utils :: globalVariables 함수를 사용하라는 지시를 받았습니다. 내가 주장 할 입장이 아니기 때문에 내가 한 일입니다.
jbryer

9
나는 그들을 무시하는 것이 최선이 될 것이라고 동의하지만, 내 코드 사용 많이 ggplot하고 data.table, 따라서이 t 정말 수정에 필요한 문제였다 다른 더 중요한 경고를 알아 차리지에서 저를 지켰다 이러한 경고의를.
Ken Williams

108
@hadley 당신은 단지 2 년 후에도 괜찮다고 생각할 때 절대로 물건을 사용하지 않을 것이라고 말해서는 안됩니다
hadley

10
새해 결심? ggplot::scale_dualAxis.sqrt채우기 패턴이있는 3D 원형 차트와 눈을 계속 뜬다.
baptiste

29

이 질문은 얼마 전에 요청 및 답변되었지만 버전 2.1.0 부터 메모를 해결할 수있는 다른 방법이 있습니다.aes_(x=~x.values,y=~y.values).


12

만약

getRversion() >= "3.1.0"

패키지의 최상위 수준에서 통화를 추가 할 수 있습니다.

utils::suppressForeignCheck(c("x.values", "y.values"))

에서:

help("suppressForeignCheck")

3
그것은 공정한 해결책입니다. 감사! 나는 이것을 고려했지만 문제는 x.valuesand와 같은 많은 변수가 y.values있기 때문에 모든 변수 를 등록해야한다는 것입니다.
briandk

4
그것은 suppressForeignCheck사용 되지 않습니다
hadley

10
실제로 최상위 는 어디에 있습니까 ? 이 파일을 어떤 파일에 추가합니까?
drmariod

9
사용자 지정에 따라 zzz.R파일은 에 저장됩니다 ./R/. 예를 들어, github.com/HughParsonage/grattan/blob/master/R/zzz.R
Hugh

6
@hadley, 무엇을 위해 사용됩니까? help ( "suppressForeignCheck")는 "런타임 계산 된 기본 심볼"을 의미하는 것으로 보이지만 대체 무엇입니까?
pdb

8

2019 년에이 문제를 해결하는 가장 좋은 방법 .datarlang패키지 의 접두사 를 사용하는 것 입니다. 이것은 치료에 R 지시 x.values하고 y.valuesA의 열로 data.frame(이 정의되지 않은 변수에 대해 불평하지 않도록).

참고 : 데이터 입력에 존재하는 것으로 미리 정의 된 열 이름이있는 경우 가장 효과적입니다.

#' @importFrom rlang .data
my_func <- function(data) {
    ggplot(data, aes(x = .data$x, y = .data$y))
}

3

패키지 레벨 문서를 제공하는 파일에 다음 코드 행을 추가하십시오.

if(getRversion() >= "2.15.1")  utils::globalVariables(c("."))

여기

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.