Каков наиболее эффективный способ выбора набора имен переменных в R data.frame? - PullRequest
37 голосов
/ 24 февраля 2012

Проблема:

Мне часто приходится выбирать набор переменных из фрейма data.frame в R. Мои исследования посвящены социальным и поведенческим наукам, и довольно часто иметь data.frame.с несколькими сотнями переменных (например, будет информация об уровне элемента для ряда вопросов опроса, демографических элементов, показателей эффективности и т. д. и т. д.).

В рамках анализа я буду частохочу выбрать подмножество переменных.Например, я могу получить:

  • описательную статистику для набора переменных
  • матрицу корреляции для набора переменных
  • факторный анализ для наборапеременные
  • предикторы в линейной модели

Теперь я знаю, что существует множество способов написания кода для выбора подмножества переменных. Quick-r имеет хороший обзор общих способов извлечения подмножеств переменных из data.frame .

например,

myvars <- c("v1", "v2", "v3")
newdata <- mydata[myvars]

Однако меня интересуетэффективность этого процесса, особенно там, где вам может понадобиться извлечь около 20 переменных из data.frame.Соглашение о присвоении имен переменным часто не является интуитивно понятным, особенно если вы унаследовали набор данных от кого-то другого, поэтому вам может быть интересно, была ли переменная Gender, gender, sex, GENDER, gender1 и т. д. Умножьте это на 20 переменных, которые необходимо извлечь, и задача запоминания имен переменных станет более сложной, чем должна быть.

Конкретный пример

Чтобы провести следующее обсуждениеКонкретно, я буду использовать bfi data.frame в пакете psych.

library(psych)
data(bfi)
df <- bfi
head(df, 1)
      A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 E1 E2 E3 E4 E5 N1 N2 N3 N4 N5 O1 O2 O3 O4
61617  2  4  3  4  4  2  3  3  4  4  3  3  3  4  4  3  4  2  2  3  3  6  3  4
      O5 gender education age
61617  3      1        NA  16
  • Как я могу эффективно выбрать произвольный набор переменных, что для конкретности, я будувыберите A1, A2, A3, A5, C2, C3, C5, E2, E3, gender, education, age?

Моя текущая стратегия

В настоящее время у меня есть ряд стратегий, которые я использую.Конечно, иногда я могу использовать такие вещи, как числовое положение переменных или соглашение об именах, и использовать либо grep для выбора, либо paste для построения.Но иногда мне нужно более общее решение.В то время я использовал следующее:

1.names (df)

В первые дни я звонил names(df), копировал имена переменных в кавычках и затем редактировал, пока не получу то, что хочу.

2.Использовать базу данных

Иногда у меня будет отдельный файл data.frame, в котором каждая переменная хранится в виде строки, и в которой есть столбцы для имен переменных, меток переменных, а также столбец, который указывает, следует ли сохранить переменную.для конкретного анализа.Затем я могу отфильтровать эту переменную include и извлечь вектор имен переменных.Я нахожу это особенно полезным, когда я разрабатываю психологический тест и для различных итераций я хочу включить или исключить определенные элементы.

3.dput (names (df))

Как однажды указал мне Хэдли Уикхем, dput - хороший вариант;Например, dput(names(df)) лучше, чем names(df), поскольку он выводит список, который уже находится в формате c("var1", "var2", ...):

dput(names(df))
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5", "gender", "education", "age")

. Затем его можно скопировать в сценарий и отредактировать.

Но может ли это быть более эффективным? 1072 * Я думаю, dput - довольно хорошая стратегия выбора переменных.Эффективность процесса во многом зависит от того, насколько вы искусны в копировании текста в сценарий и последующем редактировании списка имен до желаемых. Однако я до сих пор помню эффективность систем переменных на основе графического интерфейса пользователя.выбор.Например, в SPSS, когда вы взаимодействуете с диалоговым окном, вы можете указать и щелкнуть мышью необходимые переменные из набора данных.Вы можете нажать Shift, чтобы выбрать диапазон переменных, вы можете удерживать Shift и нажать клавишу «Вниз», чтобы выбрать одну или несколько переменных, и так далее.И затем вы можете нажать Paste и команда с извлеченными именами переменных будет вставлена ​​в ваш редактор скриптов. Итак, наконец, основной вопрос

  • Существует ли простое графическое устройство без излишеств, которое позволяет выбирать переменные из data.frame (например, что-то вроде guiselect(df) открывает окно графического интерфейса для выбора переменных) и возвращает вектор выбранных имен переменных c("var1", "var2", ...)?
  • Является ли dput лучшим общим вариантом для выбора набора имен переменных в R?Или есть лучший способ?

Обновление (апрель 2017 г.): Я опубликовал собственное понимание хорошей стратегии ниже .

Ответы [ 5 ]

23 голосов
/ 24 февраля 2012

Я лично являюсь поклонником myvars <- c(...), а затем использую mydf[,myvars] с этого момента в.

Однако для этого все равно требуется ввести исходные имена переменных (хотя бы один раз), иНасколько я читаю ваш вопрос, это именно то, о чем вы спрашиваете: «Выбор имен переменных».

Re простое графическое устройство без излишеств - недавно я познакомился сmenu функция, которая представляет собой простое графическое устройство без излишеств для выбора одного объекта из списка вариантов.Попробуйте menu(names(df),graphics=TRUE), чтобы понять, что я имею в виду (возвращает номер столбца).Это даже дает хороший текстовый интерфейс, если по какой-то причине ваша система не может выполнять графику (попробуйте с помощью graphics=FALSE, чтобы понять, что я имею в виду).

Однако это имеет ограниченное применение для вас, так как вы можетевыберите только одно имя столбца.Чтобы выбрать несколько , вы можете использовать select.list (упомянутый в ?menu в качестве альтернативы для множественного выбора):

# example with iris data (I don't have 'psych' package):
vars <- select.list(names(iris),multiple=TRUE,
                    title='select your variable names',
                    graphics=TRUE)

Это также принимает параметр graphics=TRUE (одиннажмите на все элементы, которые вы хотите выбрать).Возвращает имена переменных.

10 голосов
/ 24 февраля 2012

Вы можете использовать select.list(), например:

DF <- data.frame(replicate(26,list(rnorm(5))))
names(DF) <- LETTERS
subDF <- DF[select.list(names(DF), multiple=TRUE)]
5 голосов
/ 06 апреля 2017

Я использую следующую стратегию, чтобы сделать выбор переменных в R. эффективным.

Использование метаданных для хранения имен переменных

У меня есть фреймы данных с одной строкой на переменную для определенных наборов переменных.Например, у меня может быть личностный тест из 100 предметов.Метаданные включают имя переменной в R вместе со всей оценочной информацией (например, должен ли элемент быть изменен и т. Д.).Затем я могу извлечь имена переменных для элементов и имена шкал из этих метаданных.

Сохранение наборов переменных в именованном списке

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

Вот простой пример:

v <- list()
v$neo_items <- meta.neo$id
v$ds14_items <- meta.ds14$id
v$core_items <- c(v$neo_items, v$ds14_items)       

v$typed_scales <- c("na", "si")
v$typed_all <- c("typed_continuous_sum", "na", "si")
v$neo_facets <- sort(unique(meta.neo$facet))
v$neo_factors <- c("agreeableness", "conscientiousness", 
                   "extraversion", "neuroticism", "openness")
v$outcomes_scales <- c("healthbehavior", "socialsupport", 
                "physical_symptoms", "psychological_symptoms")

Несколько моментов можно увидеть из приведенного выше примера:

  • Часто списки переменных создаются из метаданных, которые я хранил отдельно.Так, например, у меня есть имена переменных для 240 itms neo-теста личности, хранящиеся в meta.neo$id
  • В некоторых случаях имена переменных могут быть получены из метаданных.Например, один из столбцов в моих метаданных для теста личности указывает, к какому масштабу относится элемент, а имена переменных выводятся из этого столбца, принимая значение unique этого столбца.
  • В некоторых случаях наборы переменных являются комбинацией меньших наборов.Так, например, у вас может быть один набор для предикторов, один набор для результатов и один набор, который объединяет предикторы и результаты.Разделение на предикторы и результаты может быть полезно для некоторых регрессионных моделей, а комбинированный набор может быть полезен для матрицы корреляции или факторного анализа.
  • Для более специальных списков переменных я все еще использую dput(names(df)где df - мой data.frame для генерации вектора имен символов, который затем сохраняется в списке переменных.
  • Эти списки переменных обычно размещаются после загрузки ваших данных, но до их обработки.Таким образом, их можно использовать для подготовки данных, и они, безусловно, доступны, когда вы начинаете анализ (например, прогностические модели, корреляции, описательная статистика и т. Д.).
  • Красота списков переменных заключается в том, что выможет легко использовать auto-copmlete в RStudio.Поэтому вам не нужно запоминать имена переменных или даже имена списков переменных.Вы просто набираете v$ и нажимаете tab или v$ и некоторую часть имени списка.

Использование списков переменных

Использование списков переменных довольно просто, но некоторые функциив R указывать имена переменных по-разному.

Простой и стандартный сценарий предполагает предоставление списка имен переменных в подмножество data.frame.Например,

cor(data[,v$mylist])
cor(data[,v$predictors], data[,v$outcomes])

Это немного сложнее для функций, которые требуют формул.Вам может понадобиться написать функцию.Например:

v <- list()
v$predictors <- c("cyl", "disp")
f <- as.formula(paste("mpg ~", paste(v$predictors, collapse = " + ")))
lm(f, mtcars)

Вы также можете использовать списки переменных в таких функциях, как sapply и lapply (и, вероятно, в эквивалентных значениях).Например,

Создать таблицу описательной статистики с помощью:

sapply(mydata[, v$outcomes], function(X) c(mean = mean(X), sd = sd(X)))

dput все еще полезно

Для специальных переменных или даже когда вы просто пишете коддля создания списка переменных очень полезно использовать dput.

Стандартный код - dput(names(df)), где df - ваш data.frame.Например:

 dput(names(mtcars))

Производит

 c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", 
 "gear", "carb")

Затем вы можете отредактировать эту строку, чтобы извлечь нужные переменные.Это дает дополнительное преимущество, заключающееся в уменьшении количества ошибок при вводе в коде.И это действительно важный момент.Вы не хотите тратить много времени на отладку кода, который был просто результатом опечатки.Кроме того, сообщение об ошибке Rs при неправильном вводе имени переменной ужасно.Он просто говорит «выбраны неопределенные столбцы».Он не сообщает вам, какие имена переменных были неправильными.

Если у вас большое количество переменных, вы также можете использовать ряд функций поиска строк для извлечения подмножества имен переменных:

Например,

> library(psych)
> dput(names(bfi)) #all items
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5", "gender", "education", "age")
> dput(grep("^..$", names(bfi), value = TRUE)) # two letter variable names
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5")
> dput(grep("^E.$", names(bfi), value = TRUE)) # E items
c("E1", "E2", "E3", "E4", "E5")
> dput(grep(".5$", names(bfi), value = TRUE)) # 5th items
c("A5", "C5", "E5", "N5", "O5")

Очистить существующие имена переменных и использовать соглашение об именах

Когда я получаю файл данных от кого-то другого, в именах переменных часто отсутствуют соглашения или соглашения, которые заставляют работатьс переменными, менее полезными в R. Несколько правил, которые я использую:

  • делают все переменные в нижнем регистре (необходимость думать о переменных в нижнем и верхнем регистре просто раздражает)
  • makeимена переменных по сути значимы (некоторые другие программы используют метки переменных для хранения значимых данных; R на самом деле не использует метки)
  • Сохраняйте переменные соответствующей длины (то есть не слишком длинной)До 10 символов в порядке.Более 20 раздражают.

Все эти шаги, как правило, облегчают выбор переменных, так как помнят меньше несоответствий.

Используйте завершение табуляции для отдельных имен переменных

Для отдельных переменных я обычно использую автозаполнение из фрейма данных.Например, df$ и нажмите вкладку.

Я пытаюсь использовать стиль кодирования, который позволяет мне использовать автозаполнение в максимально возможной степени.Мне не нравятся функции, которые требуют, чтобы я знал имя переменной без использования автозаполнения.Например, при подстановке data.frame я предпочитаю от

df[ df$sample == "control", ]

до

subset(df, sample == "control")

, потому что я могу автозаполнить имя переменной "sample" в верхнем примере, но не ввторой.

3 голосов
/ 24 февраля 2012

Если вам нужен метод, который игнорирует регистр переменных и, возможно, выбирает переменные на основе их «основ», тогда используйте соответствующий шаблон регулярных выражений и ignore.case- = TRUE и значение = TRUE с grep:

 dfrm <- data.frame(var1=1, var2=2, var3=3, THIS=4, Dont=5, NOTthis=6, WANTthis=7)
unlist(sapply( c("Want", "these", "var"),
   function(x) grep(paste("^", x,sep=""), names(dfrm), ignore.case=TRUE, value=TRUE) ))
#----------------
      Want       var1       var2       var3   # Names of the vector
"WANTthis"     "var1"     "var2"     "var3"   # Values matched
> dfrm[desired]
  WANTthis var1 var2 var3
1        7    1    2    3
0 голосов
/ 24 февраля 2012

Вы имеете в виду select?

sub_df = subset(df, select=c("v1","v2","v3"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...