Подтвердить что ты не робот

Использовать имена переменных в функциях dplyr

Я хочу использовать имена переменных как строки в функциях dplyr. См. Пример ниже:

df <- data.frame( 
      color = c("blue", "black", "blue", "blue", "black"), 
      value = 1:5)
filter(df, color == "blue")

Он работает отлично, но я хотел бы ссылаться на color на строку, примерно так:

var <- "color"
filter(df, this_probably_should_be_a_function(var) == "blue").

Я был бы счастлив сделать это с помощью любых средств и с удовольствием использовать простой для чтения синтаксис dplyr.

4b9b3361

Ответ 1

Для версий dplyr [0.3 - 0.7) (? - июнь 2017 г.)

(Более свежие версии dplyr приведены в других ответах на этот вопрос).

Начиная с dplyr 0.3 каждая функция dplyr использующая нестандартную оценку (NSE, см. Пост релиза и виньетка), имеет стандартную близнец оценки (SE), заканчивающийся подчеркиванием. Они могут быть использованы для передачи переменных. Для filter это будет filter_. Используя filter_ вы можете передать логическое условие в виде строки.

filter_(df, "color=='blue'")

#   color value
# 1  blue     1
# 2  blue     3
# 3  blue     4

Построить строку с логическим условием, конечно, просто

l <- paste(var, "==",  "'blue'")
filter_(df, l)

Ответ 2

В более новых версиях мы можем использовать, мы можем создавать переменные в кавычках, а затем в кавычках (UQ или !!) для оценки

var <- quo(color)
filter(df, UQ(var) == "blue")
#   color value
#1  blue     1
#2  blue     3
#3  blue     4

Из-за приоритета оператора мы можем потребовать () обернуть вокруг !!

filter(df, (!!var) == "blue")
#   color value
#1  blue     1
#2  blue     3
#3  blue     4

С новой версией, || имеют более высокий приоритет, поэтому

filter(df, !! var == "blue")

должно работать (как прокомментировал @Moody_Mudskipper)

Более старый вариант

Мы также можем использовать:

 filter(df, get(var, envir=as.environment(df))=="blue")
 #color value
 #1  blue     1
 #2  blue     3
 #3  blue     4

РЕДАКТИРОВАТЬ: переставил порядок решений

Ответ 3

Начиная с версии 0.7 некоторые вещи снова изменились.

library(dplyr)
df <- data.frame( 
  color = c("blue", "black", "blue", "blue", "black"), 
  value = 1:5)
filter(df, color == "blue")

# it was already possible to use a variable for the value
val <- 'blue'
filter(df, color == val)

# As of dplyr 0.7, new functions were introduced to simplify the situation
col_name <- quo(color) # captures the current environment
df %>% filter((!!col_name) == val)

# Remember to use enquo within a function
filter_col <- function(df, col_name, val){
  col_name <- enquo(col_name) # captures the environment in which the function was called
  df %>% filter((!!col_name) == val)
}
filter_col(df, color, 'blue')

Более общие случаи объясняются в виньетке программирования dplyr.

Ответ 4

Часто спрашивали, но все же нет легкой поддержки afaik. Однако в отношении этой публикации:

eval(substitute(filter(df, var == "blue"), 
                list(var = as.name(var))))
#   color value
# 1  blue     1
# 2  blue     3
# 3  blue     4

Ответ 5

Вот один из способов сделать это, используя функцию sym() в пакете rlang:

library(dplyr)

df <- data.frame( 
  main_color = c("blue", "black", "blue", "blue", "black"), 
  secondary_color = c("red", "green", "black", "black", "red"),
  value = 1:5, 
  stringsAsFactors=FALSE
)

filter_with_quoted_text <- function(column_string, value) {
    col_name <- rlang::sym(column_string)
    df1 <- df %>% 
      filter(UQ(col_name) == UQ(value))
    df1
}

filter_with_quoted_text("main_color", "blue")
filter_with_quoted_text("secondary_color", "red")

Ответ 6

новый с rlang версией> = 0.4.0

.data теперь распознается как способ ссылки на родительский фрейм данных, поэтому ссылка по строке работает следующим образом:

var <- "color"
filter(df, .data[[var]] == "blue")

Если переменная уже является символом, то {{}} будет правильно разыменовывать ее

Пример 1:

var <- quo(color)
filter(df, {{var}} == "blue")

или более реалистично

f <- function(v) {
    filter(df, {{v}} == "blue")
}
f(color) # Curly-curly provides automatic NSE support