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

Каков наиболее эффективный способ выбора набора имен переменных из R data.frame?

Проблема:

Мне часто нужно выбрать набор переменных из 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), скопировал имена цитируемых переменных и затем отредактировал, пока у меня не будет того, что я хочу.

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

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

3. dput (имена (ДФ))

Как Хэдли Уикхем однажды указал мне 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")

Затем это можно скопировать в script и отредактировать.

Но может ли он быть более эффективным

Я думаю, dput - довольно хорошая стратегия выбора переменных. Эффективность процесса во многом зависит от того, насколько вы умеете копировать текст в свой script, а затем редактируете список имен до желаемых.

Тем не менее, я до сих пор помню эффективность графических систем выбора переменных. Например, в SPSS, когда вы взаимодействуете с диалоговым окном, вы можете указать и щелкнуть мышью переменные, которые вы хотите получить из набора данных. Вы можете щелкнуть мышью, чтобы выбрать диапазон переменных, вы можете удерживать shift и нажимать клавишу "вниз", чтобы выбрать одну или несколько переменных, и так далее. И затем вы можете нажать paste, а команда с выделенными именами переменных вставляется в ваш редактор script.

Итак, наконец, основной вопрос

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

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

4b9b3361

Ответ 1

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

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

Перейдите к простому графическому устройству без излишеств - я недавно познакомился с функцией menu, которая представляет собой простое без излишеств GUI-устройство для выбора одного объекта из списка вариантов. Попробуйте 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 (один клик по всем элементам, которые вы хотите выбрать). Он возвращает имена переменных.

Ответ 2

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

DF <- data.frame(replicate(26,list(rnorm(5))))
names(DF) <- LETTERS
subDF <- DF[select.list(names(DF), multiple=TRUE)]

Ответ 3

Если вам нужен метод, который игнорирует случай переменных и, возможно, выбирает переменные на основе их "стеблей", то используйте соответствующий шаблон регулярного выражения и ignore.case- = TRUE и value = 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

Ответ 4

Я использую следующую стратегию, чтобы сделать выбор переменных в 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 томов теста личности, хранящегося в meta.neo$id
  • В некоторых случаях имена переменных могут быть получены из метаданных. Например, один из столбцов в моих метаданных для теста личности указывает, к какой шкале относится элемент, а имена переменных выводятся из этого столбца, принимая значение unique этого столбца.
  • В некоторых случаях переменные наборы представляют собой комбинацию меньших множеств. Например, у вас может быть один набор для предикторов, один набор для результатов и один набор, который объединяет предиктора и результаты. Разделение на предсказатели и результаты может быть полезно для некоторых моделей регрессии, и объединенный набор может быть полезен для корреляционной матрицы или анализа факторов.
  • Для более специальных списков переменных я все еще использую dput(names(df), где df - это мой data.frame для генерации вектора имен символов, который затем сохраняется в списке переменных.
  • Эти списки переменных обычно размещаются после загрузки ваших данных, но перед тем, как вы это сделаете. Таким образом, они могут использоваться для подготовки данных, и они, безусловно, доступны при запуске анализов (например, прогностических моделей, корреляций, описательной статистики и т.д.).
  • Красота списков переменных состоит в том, что вы можете легко использовать автокоманду в RStudio. Поэтому вам не нужно запоминать имена переменных или даже имена списков переменных. Просто введите v$ и нажмите вкладку или 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 при неправильном указании имени переменной ужасно. Он просто говорит, что выбрано "undefined columns". Он не говорит вам, какие имена переменных были неправильными.

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

Например

> 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. Несколько правил, которые я использую:

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

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

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

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

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

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

to

subset(df, sample == "control")

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

Ответ 5

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

sub_df = subset(df, select=c("v1","v2","v3"))