Проверка класса столбца в функции, которая использует аккуратную оценку - PullRequest
1 голос
/ 11 июля 2019

Я не называю имя столбца как строку, но как я могу проверить класс в операторе if, если я не ссылаюсь на имя столбца как строку:

Моя проблема связана сif statement ниже: я пробовал rlang::as_name, quote и т. Д.

df <- tibble::tibble( time_text = as.character(as.POSIXct("2018-02-03 08:00:00", tz = "UTC") + rnorm(100, 0, 60*60*60)))

date_from_text <- function(df, x){

  if(!class(df[[deparse(x)]]) %in% c("POSIXct", "POSIXt" )) {

  x <- rlang::enquo(x)
  name <- rlang::quo_name(x)

 out <-  df %>%
    dplyr::mutate(!!name := lubridate::ymd_hms(!!x))
  }
  else {
    stop("Seems that column is in the right format already")
       }  
}

date_from_text(df, time_text)
 Error in deparse(x) : object 'time_text' not found 

Ответы [ 3 ]

3 голосов
/ 11 июля 2019

Работает, когда вы используете x <- rlang::enquo(x) и name <- rlang::quo_name(x) до if -статации:

date_from_text <- function(df, x){

  x <- rlang::enquo(x)
  name <- rlang::quo_name(x)

  if(!inherits(df[[name]], c("POSIXct", "POSIXt"))) {

    out <- dplyr::mutate(df, !!name := lubridate::ymd_hms(!!x))

  } else {

    stop("Seems that column is in the right format already")

  }  
}

Я изменил требование в if -статменте на !inherits(df[[name]], c("POSIXct", "POSIXt")).
В вашем исходном коде будет проверен только первый элемент вектора класса, тогда как наследуется проверка, наследуется ли какой-либо из указанных классов.

my.df <- tibble::tibble(time_text = as.character(as.POSIXct("2018-02-03 08:00:00", tz = "UTC") + rnorm(100, 0, 60*60*60)))

my.df2 <- date_from_text(my.df, time_text)
my.df2
# A tibble: 100 x 1
#   time_text          
#   <dttm>             
# 1 2018-02-06 18:38:46
# 2 2018-01-31 16:16:15
# 3 2018-02-04 05:52:32
# 4 2018-02-05 23:31:50
# 5 2018-02-06 13:00:34
# 6 2018-02-01 16:16:24
# 7 2018-02-05 15:09:45
# 8 2018-02-04 04:23:00
# 9 2018-02-03 06:55:18
# 10 2018-01-29 01:06:26
# ... with 90 more rows

date_from_text(my.df2, time_text)

Ошибка в date_from_text (my.df2, time_text): кажется, что столбец уже в правильном формате

Спасибо @KonradRudolph за улучшение этого ответа сего комментарии.

2 голосов
/ 11 июля 2019

Мы также можем использовать новый оператор curly-curly ({{}}) из rlang

library(rlang)

date_from_text <- function(df, x){

  if (!class(df %>% pull({{x}})) %in% c("POSIXct", "POSIXt")) {

      x <- rlang::enquo(x)
      name <- rlang::quo_name(x)
      df %>% mutate(!!name := lubridate::ymd_hms({{x}}))

   } else {
     stop("Seems that column is in the right format already")
   }  
}

df1 <- date_from_text(df, time_text)

df1
# A tibble: 100 x 1
#   time_text              
#   <dttm>                 
# 1 2018-02-05 06:47:00.947
# 2 2018-02-06 13:25:36.656
# 3 2018-01-31 18:45:57.358
# 4 2018-02-05 02:16:56.179
# 5 2018-02-06 15:43:30.417
# 6 2018-02-07 14:59:56.203
# 7 2018-02-01 04:25:29.382
# 8 2018-01-31 19:11:13.136
# 9 2018-02-02 18:47:06.812
#10 2018-02-03 17:31:45.790
# … with 90 more rows

date_from_text(df1, time_text)

Ошибка в date_from_text (df1, time_text): Кажется, что столбец уже в правильном формате

1 голос
/ 11 июля 2019

или укажите название столбца, который вы хотите проверить

date_from_text <- function(df, x){

  if( !class( df[[x]] ) %in% c( "POSIXct", "POSIXt" )) {
    df[[x]] <- lubridate::ymd_hms( df[[x]] )
    return( df[[x]] )
  }
  else {
    stop( "Seems that column is in the right format already" )
  }  

}

date_from_text( df, "time_text" )
...