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

Как я могу сказать select() в dplyr, что строка, которую он видит, является именем столбца в кадре данных

Я пробовал искать, но не нашел ответа на этот вопрос.

Я пытаюсь использовать оператор select в dplyr, но у меня возникают проблемы при попытке отправить его. Мой вопрос: как я могу указать select(), что строка, которую он видит, является именем столбца в кадре данных?

например. это прекрасно работает

select(df.main.scaled, var1, var3)
select(df.main.scaled, var2, var4)

но это не работает:

select(df.main.scaled, names.gens[i,1], names.gens[i,2])

где

> names.genx <- c("var1","var2")
> names.geny <- c("var3","var4")
> names.gens <- cbind(names.genx, names.geny)
> names.gens
     names.genx names.geny
[1,] "var1"     "var3"    
[2,] "var2"     "var4"  

Чтобы быть ясным, все строки в именах .gens - это имена столбцов в фрейме данных.

Спасибо.

4b9b3361

Ответ 1

Я понял это через пробную версию и ошибку. Если кто-то любопытен, сделал что-то вроде этого:

lapply(names.gens, as.name)
select(df.main.scaled, eval(names.gens[[i]]), eval(names.gens[[i+someindex]]))

Ответ 2

Выберите, кажется, работает с индексами столбцов (dplyr 0.2), поэтому просто сопоставьте свои имена с их индексом и используйте их для выбора столбцов.

myCols <- c("mpg","disp")
colNums <- match(myCols,names(mtcars))
mtcars %>% select(colNums)

Ответ 3

В более поздних версиях dplyr это возможно в select с one_of, как в

my_cols <- c('mpg', 'disp')
mtcars %>% select(one_of(my_cols))

Ответ 4

Я столкнулся с этим, и я подумал, что должен упомянуть, что это было решено в более новых версиях dplyr.

myTest = data_frame(
  var1 = 1, 
  var2 = 2,
  var3 = 3,
  var4 = 4)

i = 1

myTest %>%
  select_(.dots = 
     c(names.gens[i,1], names.gens[i,2]) %>% unname)

Ответ 5

Вы можете использовать get(), чтобы получить объект, названный строкой в ​​текущей среде. Итак:

R> iris %>% select(Species, Petal.Length) %>% head(3)
  Species Petal.Length
1  setosa          1.4
2  setosa          1.4
3  setosa          1.3
R> iris %>% select('Species', 'Petal.Length') %>% head(3)
Error in abs(ind[ind < 0]) : 
  non-numeric argument to mathematical function     
R> iris %>% select(get('Species'), get('Petal.Length')) %>% head(3)
  Species Petal.Length
1  setosa          1.4
2  setosa          1.4
3  setosa          1.3
R> s <- 'Species'
R> p <- 'Petal.Length'
R> iris %>% select(get(s), get(p)) %>% head(3)
  Species Petal.Length
1  setosa          1.4
2  setosa          1.4
3  setosa          1.3

Ответ 6

[Изменить - некоторые из приведенных ниже устарели с выпуском dplyr 0.7 - см. здесь]

Вопрос о разнице между стандартной оценкой и нестандартной оценкой.

tl; dnr: Вы можете использовать аналог "стандартной оценки" dplyr::select, который равен dplyr::select_.

Это позволяет вам указывать имена столбцов в виде переменных, содержащих строки:

dplyr::select_(df.main.scaled, names.gens[i,1], names.gens[i,2])

Вот несколько деталей, которые пытаются объяснить, как это работает:

Нестандартная оценка и функция выбора в dplyr

Нестандартная оценка - это оценка кода нестандартными способами. Часто это означает захват выражений до их оценки и оценку их в другой среде (контексте/сфере) до нормального. Когда вы указываете dplyr::select имена столбцов без кавычек, dplyr использует нестандартную оценку, чтобы интерпретировать их как столбцы.

Примеры использования dplyr:: select

Предположим, что у нас есть следующий фрейм данных:

df <- tibble::data_frame(a = 1:5, b = 6:10, c = 11:15, d = 16:20)

Простой пример оператора select выглядит следующим образом:

r <- dplyr::select(df, a, b)

Это пример NSE, потому что a и b не являются переменными, которые существуют в глобальной среде. Вместо поиска a и b в глобальном пространстве имен dplyr::select направляет R для поиска переменных a и b в контексте dataframe df. Вы можете думать о том, что среда немного похожа на список, а a и b - на клавиши. Итак, следующее немного похоже на поиск R для поиска df$a и df$b

Аргументы функции в R promises, которые не оцениваются немедленно. Они могут быть захвачены как выражения, а затем выполняться в другой среде.

Это прекрасно, если мы знаем, что мы хотим заранее выбрать столбцы a и b. Но что, если эти столбцы неизвестны заранее и хранятся в переменной.

columns_to_select <- c("a", "b")

Не работает следующее:

 dplyr::select(df, columns_to_select)

Эта ошибка говорит нам, что в кадре данных нет столбца, называемого "columns_to_select". Аргумент columns_to_select был оценен в контексте фрейма данных, поэтому R попытался сделать что-то вроде df$columns_to_select и обнаружил, что столбец не существует.

Как мы это исправим?

Функции Tidyverse всегда обеспечивают 'escape hatch', которые позволяют обойти это ограничение. dplyr vignette говорит:" Каждая функция dplyr, использующая NSE, также имеет версию, использующую SE. Имя версии SE всегда является именем NSE с _ в конце. '

Что это значит?

Мы можем попробовать следующее, но мы обнаруживаем, что оно не работает:

# Does not work
r <-dplyr::select_(df, columns_to_select)

В отличие от захвата аргумента columns_to_select функции select_ и интерпретации его как имени столбца, columns_to_select оценивается стандартным способом, разрешая c("a", "b").

Это то, что мы хотим, за исключением того, что каждый аргумент select_ является единственным столбцом, и мы просто предоставили вектор символов длины два для представления одного столбца.

Таким образом, приведенный выше код возвращает кусочек с одним столбцом, а это не то, что мы хотели. (Используется только первый элемент - "a" в символьном векторе, все остальное игнорируется).

Одно из решений этой проблемы заключается в следующем, но предполагает, что columns_to_select содержит ровно два элемента:

col1 <- columns_to_select[1]
col2 <- columns_to_select[2]
r <- dplyr::select_(df,col1, col2)

Как мы обобщаем это на случай, когда columns_to_select может иметь произвольное количество элементов?

Решение состоит в использовании необязательного аргумента .dots.

 dplyr::select_(df, .dots=columns_to_select)

Это имеет некоторое объяснение

В R конструкция ... позволяет создавать функции с переменным (произвольным) числом аргументов. ... доступен внутри функции и позволяет тело функции получить доступ ко всем аргументам. См. Также здесь.

Очень простой пример:

addition <- function(...) {
  args <- list(...)
  sum(unlist(args))
}
r <- addition(1,2,3)

Однако это не сразу помогает нам здесь. Он фактически уже реализован в функции select_ и просто позволяет нам предоставить произвольное количество имен столбцов в качестве аргументов, например. select_(df, "a", "b", "c", "d").

Нам нужен механизм, похожий на ..., но позволяющий передать что-то вроде ... в функцию как один аргумент. Это именно то, что делает .dots.

Обратите внимание, что .dots не предоставляется select, поскольку он предназначен для интерактивного использования.

Ответ 7

В dplyr 0.1.2 существует обходное решение с использованием регулярных выражений и совпадений (см. комментарий к файлу ниже для получения информации о прямой поддержке в будущих версиях). Регулярное выражение, такое как ^(x1|x2|x3)$, соответствует именам точных переменных, поэтому нам просто нужно построить такое выражение из вектора с именами переменных. Вот код

# load libraries
library(dplyr)
library(stringr)
# create data.frame
df = data.frame(
    x = rep(0,5),
    y = 1,
    var = 2,
    another_var = 5,
    var.4 = 6
)
# function to construct reg exp from vector with variable names
varlist = function(x) {
    x = str_c('^(',paste(x, collapse='|'),')$')
    x = str_replace_all(x,'\\.','\\\\.')
    return(x)
}
# select variables based on vector of variable names
vars = c('y','another_var','var.4')
df %.%
    select(matches(varlist(vars)))