Динамически выбирать столбцы фрейма данных с помощью $ и вектора имен столбцов

Я хочу заказать кадр данных на основе разных столбцов, один на очереди. У меня есть вектор символов с соответствующими именами столбцов, на которых должен основываться order :

 parameter <- c("market_value_LOCAL", "ep", "book_price", "sales_price", "dividend_yield", "beta", "TOTAL_RATING_SCORE", "ENVIRONMENT", "SOCIAL", "GOVERNANCE") 

Я хочу перебрать имена в parameter и динамически выбрать столбец, который будет использоваться для order моих данных:

 Q1_R1000_parameter <- Q1_R1000[order(Q1_R1000$parameter[X]), ] 

где X равно 1:10 (потому что у меня есть 10 элементов в parameter ).


Чтобы сделать мой пример воспроизводимым, рассмотрим dataset mtcars и некоторые имена переменных, хранящиеся в символьных векторных cols . Когда я пытаюсь выбрать переменную из mtcars с помощью динамического поднабора cols , аналогично выше ( Q1_R1000$parameter[X] ), столбец не выбран:

 cols <- c("cyl", "am") mtcars$cols[1] # NULL 

Вы не можете делать такие подмножества с $ . В исходном коде ( R/src/main/subset.c ) говорится:

/ * Оператор $ subset.
Мы должны обязательно оценить только первый аргумент.
Второй будет символом, который нужно сопоставить, а не оценивать.
* /

Второй аргумент? Какие?! Вы должны понимать, что $ , как и все остальное в R, (включая, например, ( , + , ^ т. Д.), Является функцией, которая принимает аргументы и оценивается. df$V1 можно переписать как

 `$`(df , V1) 

или действительно

 `$`(df , "V1") 

Но…

 `$`(df , paste0("V1") ) 

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

Вместо этого используйте [ (или [[ если вы хотите извлечь только один столбец в качестве вектора).

Например,

 var <- "mpg" #Doesn't work mtcars$var #These both work, but note that what they return is different # the first is a vector, the second is a data.frame mtcars[[var]] mtcars[var] 

Вы можете выполнить заказ без циклов, используя do.call чтобы построить вызов на order . Ниже приведен воспроизводимый пример:

 # set seed for reproducibility set.seed(123) df <- data.frame( col1 = sample(5,10,repl=T) , col2 = sample(5,10,repl=T) , col3 = sample(5,10,repl=T) ) # We want to sort by 'col3' then by 'col1' sort_list <- c("col3","col1") # Use 'do.call' to call order. Seccond argument in do.call is a list of arguments # to pass to the first argument, in this case 'order'. # Since a data.frame is really a list, we just subset the data.frame # according to the columns we want to sort in, in that order df[ do.call( order , df[ , match( sort_list , names(df) ) ] ) , ] col1 col2 col3 10 3 5 1 9 3 2 2 7 3 2 3 8 5 1 3 6 1 5 4 3 3 4 4 2 4 3 4 5 5 1 4 1 2 5 5 4 5 3 5 

Если я правильно понял, у вас есть вектор, содержащий имена переменных и хотел бы пропустить каждое имя и отсортировать данные по ним. Если это так, этот пример должен иллюстрировать решение для вас. Основная проблема в вашем (полный пример не завершен, поэтому я не уверен, что еще вам может не order(Q1_R1000[,parameter[X]]) ) заключается в том, что он должен быть order(Q1_R1000[,parameter[X]]) вместо order(Q1_R1000$parameter[X]) , поскольку параметр является внешним объектом, который содержит имя переменной, противоположное прямому столбцу вашего фрейма данных (который, когда $ будет подходящим).

 set.seed(1) dat <- data.frame(var1=round(rnorm(10)), var2=round(rnorm(10)), var3=round(rnorm(10))) param <- paste0("var",1:3) dat # var1 var2 var3 #1 -1 2 1 #2 0 0 1 #3 -1 -1 0 #4 2 -2 -2 #5 0 1 1 #6 -1 0 0 #7 0 0 0 #8 1 1 -1 #9 1 1 0 #10 0 1 0 for(p in rev(param)){ dat <- dat[order(dat[,p]),] } dat # var1 var2 var3 #3 -1 -1 0 #6 -1 0 0 #1 -1 2 1 #7 0 0 0 #2 0 0 1 #10 0 1 0 #5 0 1 1 #8 1 1 -1 #9 1 1 0 #4 2 -2 -2 

Использование dplyr обеспечивает простой синтаксис для сортировки кадров данных

 library(dplyr) mtcars %>% arrange(gear, desc(mpg)) 

Возможно, было бы полезно использовать версию NSE для динамического создания списка сортировки

 sort_list <- c("gear", "desc(mpg)") mtcars %>% arrange_(.dots = sort_list) 
 Q1_R1000[do.call(order, Q1_R1000[parameter]), ] 

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

Я написал функцию, чтобы вернуть первое допустимое имя столбца в списке, а затем использовать это …

 # Return the string name of the first name in names that is a column name in tbl # else null ChooseCorrectColumnName <- function(tbl, names) { for(n in names) { if (n %in% colnames(tbl)) { return(n) } } return(null) } then... cptcodefieldname = ChooseCorrectColumnName(file, c("CPT", "CPT.Code")) icdcodefieldname = ChooseCorrectColumnName(file, c("ICD.10.CM.Code", "ICD10.Code")) if (is.null(cptcodefieldname) || is.null(icdcodefieldname)) { print("Bad file column name") } # Here we use the hash table implementation where # we have a string key and list value so we need actual strings, # not Factors file[cptcodefieldname] = as.character(file[cptcodefieldname]) file[icdcodefieldname] = as.character(file[icdcodefieldname]) for (i in 1:length(file[cptcodefieldname])) { cpt_valid_icds[file[cptcodefieldname][i]] <<- unique(c(cpt_valid_icds[[file[cptcodefieldname][i]]], file[icdcodefieldname][i])) } 

если вы хотите выбрать столбец с определенным именем, просто выполните

 A=mtcars[,which(conames(mtcars)==cols[1])] #and then colnames(mtcars)[A]=cols[1] 

вы можете запустить его в цикле, а также наоборот, чтобы добавить динамическое имя, например, если A – это кадр данных, а xyz – столбец, который будет называться как x, тогда мне это нравится

 A$tmp=xyz colnames(A)[colnames(A)=="tmp"]=x 

снова это также можно добавить в цикл

  • Одновременно слияние нескольких кадров данных в списке
  • Почему суммировать или мутировать не работать с group_by при загрузке `plyr` после` dplyr`?
  • Только чтение ограниченного количества столбцов
  • Как назвать переменные «на лету»?
  • Замена NA с последним значением, отличным от NA
  • Проверьте, содержит ли вектор данный элемент
  • Вычислить среднее по группе
  • Удаление дублированных строк
  • Как создать последовательный индекс на основе переменной группировки в фрейме данных
  • Постройте два графика в одном графике в R
  • Установка кривой плотности на гистограмму в R
  • Давайте будем гением компьютера.