Выберите несколько столбцов с помощью dplyr::select() с номерами в качестве имен

Скажем, у меня есть следующий фрейм данных:

a <- runif(10)
dd <- as.data.frame(t(a))
names(dd) <- c("ID", "a", "a2", "b", "b2", "f", "XXX", "1", "4", "8")

В dplyr есть хороший способ выбрать количество столбцов. Например, чтобы выбрать столбцы между столбцами a и столбцами f, я могу использовать

dd %>% dplyr::select(a:f)

В моей проблеме столбцы последней части фрейма данных могут различаться, но они всегда имеют в качестве имени число от 1 до 99. Однако я не могу сделать тот же трюк, что и выше:

> dd %>% select(1:99)
Error: Position must be between 0 and n
> dd %>% select("1":"99")
Error: Position must be between 0 and n

Это связано с тем, что использование select() пытается таким образом выбрать столбцы по положению.

Я хотел бы иметь возможность получить фрейм данных со всеми столбцами между a и f, а также с метками, которые являются числами между 1 и 99. Можно ли это сделать за один раз с select()?


person Theodor    schedule 29.06.2016    source источник


Ответы (2)


Имена столбцов, начинающиеся с цифры, например "1" и "8" в ваших данных, не являются синтаксически допустимыми именами (см. ?make.names). Затем см. раздел «Имена и идентификаторы» в ?Quoutes: «можно использовать другие [синтаксически недопустимые] имена, если они заключены в кавычки. Предпочтительной кавычкой является обратная кавычка».

Таким образом, заверните недопустимые имена столбцов в обратные кавычки (`):

dd %>% dplyr::select(a:f, `1`:`8`)

#           a        a2         b        b2          f         1         4         8
# 1 0.2510023 0.4109819 0.6787226 0.4974859 0.01828614 0.7449878 0.1648462 0.5875638

Другой вариант — использовать SE-версию select, select_:

dd %>% dplyr::select_(.dots = c("a", "a2", ..., "1", "4", "8"))
person AlexR    schedule 29.06.2016
comment
есть ли способ получить что-то вроде 1:99, даже если столбца 99 нет в этом конкретном наборе данных? - person Theodor; 29.06.2016
comment
@Theodor Не напрямую, но с помощью функции select_ вы можете передать ей массив имен столбцов, поэтому вы можете сделать что-то вроде select_(.dots = colnames(dd)[colnames(dd) %in% as.character(1:99)]) в качестве обходного пути. - person AlexR; 29.06.2016

Мы можем выбрать столбцы a:f и добавить индекс числовых столбцов, преобразовав имена столбцов в числовые:

dd %>% 
  select(a:f, which(!is.na(as.numeric(colnames(dd)))))
person zx8754    schedule 29.06.2016