Превосходно, чем ошибка, связанная с ошибкой в ​​отношении знаков и предложений

Я столкнулся с проблемой при использовании dplyr в функции. При фильтрации на основе запроса знак>, по-видимому, вызывает проблему, при которой данные не возвращаются.

Например:

temp_df <- data.frame(
startdate_c = as.Date(c("2011-08-08", "2007-09-01", "2012-01-01", "2012-10-26", "2012-12-01", 
                "2016-01-01", "2006-06-01", "2009-04-01", "2005-02-09", "2004-08-01")),
enddate_c = as.Date(c("2011-08-14", "2012-09-04", "2014-06-06", "2014-02-28", "2013-04-05",  
              "2016-12-01", "2008-04-18", "2009-08-16", "2006-04-30", "2007-06-02")))

Вот урезанная версия функции:

filter_f <- function(df, startdate = NULL, enddate = NULL) {

  if(!missing(startdate)) {
    start_var <- enquo(startdate)
  } else if("startdate_c" %in% names(df)) {
    start_var <- quo(startdate_c)
  } else {
    stop("No valid startdate found")
  }

  if(!missing(enddate)) {
    end_var <- enquo(enddate)
  } else if("enddate_c" %in% names(df)) {
    end_var <- quo(enddate_c)
  } else {
    stop("No valid enddate found")
  }

  df <- df %>%
    filter(!!start_var <= as.Date("2011-12-31") &
             !!end_var >= as.Date("2011-01-01"))

  return(df)
}

Ожидаемый результат:

  startdate_c  enddate_c
1  2011-08-08 2011-08-14
2  2007-09-01 2012-09-04
3  2012-01-01 2014-06-06
4  2012-10-26 2014-02-28
5  2012-12-01 2013-04-05
6  2016-01-01 2016-12-01

Вместо этого возвращается пустой фрейм данных.

Если я настрою код и назову дату окончания, а не использую запрос, это сработает:

filter_f2 <- function(df, startdate = NULL, enddate = NULL) {

  if(!missing(startdate)) {
    start_var <- enquo(startdate)
  } else if("startdate_c" %in% names(df)) {
    start_var <- quo(startdate_c)
  } else {
    stop("No valid startdate found")
  }

  if(!missing(enddate)) {
    end_var <- enquo(enddate)
  } else if("enddate_c" %in% names(df)) {
    end_var <- quo(enddate_c)
  } else {
    stop("No valid enddate found")
  }

  df <- df %>%
    filter(!!start_var <= as.Date("2011-12-31") &
             enddate_c >= as.Date("2011-01-01"))

  return(df)
}

Код для создания запросов startdate и enddate идентичен, и когда я переключаю фильтр так, чтобы начальная дата имела знак> =, снова возникает проблема с пустым df. Это ошибка в dplyr или я что-то не так делаю?


person GenericNameNumber    schedule 01.11.2017    source источник
comment
Ваш ожидаемый результат имеет несколько строк, которые, я думаю, следует отфильтровать.   -  person Frank    schedule 01.11.2017


Ответы (1)


Это проблема порядка операций. Операторы сравнения (<= и >=) имеют более высокий приоритет, чем оператор !. Вам нужно сделать

  df <- df %>%
    filter((!!start_var) <= as.Date("2011-12-31") &
             (!!end_var) >= as.Date("2011-01-01"))

Почему-то кажется, что кавычки имеют отрицательные значения? Наблюдать

xvar <- quo(x)
quo(!!xvar <= 0)
# ~TRUE
quo(!!xvar >= 0)
# ~FALSE

Сравнить с ...

quo((!!xvar) <= 0)
# ~(~x) <= 0
quo((!!xvar) >= 0)
# ~(~x) >= 0

И наконец (по причинам, которые я не совсем понимаю)

quo(x) <= 4
# [1] TRUE
quo(x) >= 4
# [1] FALSE

что также, кажется, связано с формулами

(~x) <= 2
# [1] TRUE
(~x) >= 2
# [1] FALSE
person MrFlick    schedule 01.11.2017
comment
Спасибо, это сработало. Полезно знать о том, что вопросы тоже отрицательные. - person GenericNameNumber; 01.11.2017