Сортировка кадра данных по нескольким столбцам по списку имен столбцов - PullRequest
0 голосов
/ 10 апреля 2019

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

DT <-data.frame(avar = c(1,4,3,1), bvar = c("a","f","s","b"), cvar = c(3,4,5,2))

sort1 <-c("avar", "cvar")
sort2 <-c("avar", "bvar")
sorting <-list(sort1,sort2)
DT2<-list()

for (i in 1:2) {
  sorter<- sorting[[i]]
   #THE FOLLOWING SOLUTION WORKS!!!
   DT2[[i]] <- DT[do.call(order,DT[as.character(sorting[[i]])]),]       
}

Под сортировкой по c ("avar", "cvar") я подразумеваю, что данные должны сначала сортироваться по avar, и (еслиесть два значения avar, которые одинаковы), то cvar.Другими словами, результат сортировки по этому вектору должен быть только один отсортированный кадр данных (не список).То же самое с сортировкой по c ("avar", "bvar").Выше «ps1» обозначает одно из предложенных решений.Это дает мне DT2 [[1]], который является списком двух фреймов данных.это не то, что мне нужно.DT2 должен быть списком двух фреймов данных.DT2 [[1]] должен быть одним фреймом данных.

Хочу также подчеркнуть, что эта сортировка мне нужна для выполнения цикла, а не передачи списка («сортировки») команде.Другими словами, первая итерация должна сортировать базу данных по первому элементу списка сортировки, который является вектором «сортировщиком» в моем коде.В реальном приложении данные на разных итерациях не совпадают с набором данных.

После первого цикла DT2 [[1]] должен быть отсортирован следующим образом:

avar  bvar  cvar
1     b     2
1     a     3
3     s     5
4     f     4    

после второгоЦикл DT2 [[2]] должен быть отсортирован следующим образом:

avar  bvar  cvar
1     a     3
1     b     2
3     s     5
4     f     4    

В реальной жизни у меня также может быть разное количество сортирующих столбцов на разных итерациях.

Относительно предлагаемых решений, использующих "Функция map ": у меня загружены некоторые геопространственные пакеты (mapproj, fiftystater, geofacet), поэтому функция" map "не работает так, как предлагается, если я не выгружу эти пакеты.Есть ли способ получить право использовать встроенную функцию «карта» вместо функции геопространственной карты?

Спасибо за помощь!

Ответы [ 4 ]

1 голос
/ 10 апреля 2019

A dplyr + purrr раствор

library(purrr)
library(dplyr)
map(sorting, ~arrange(DT, !!!syms(.x)))
#[[1]]
#  avar bvar cvar
#1    1    b    2
#2    1    a    3
#3    3    s    5
#4    4    f    4
#
#[[2]]
#  avar bvar cvar
#1    1    a    3
#2    1    b    2
#3    3    s    5
#4    4    f    4
1 голос
/ 10 апреля 2019

Используя базу R, мы можем применить order к выбранным столбцам в sorting, используя do.call.Мы используем lapply, чтобы получить список фреймов данных

lapply(sorting, function(x) DT[do.call(order, DT[x]), ])


#[[1]]
#  avar bvar cvar
#4    1    b    2
#1    1    a    3
#3    3    s    5
#2    4    f    4

#[[2]]
#  avar bvar cvar
#1    1    a    3
#4    1    b    2
#3    3    s    5
#2    4    f    4
0 голосов
/ 11 апреля 2019
The following solution works for me! Other proposed solutions I tried failed to sort by two variables in a given vector simultaneously.

DT <-data.frame(avar = c(1,4,3,1), bvar = c("a","f","s","b"), cvar = c(3,4,5,2))

sort1 <-c("avar", "cvar")
sort2 <-c("avar", "bvar")
sorting <-list(sort1,sort2)
DT2<-list()

for (i in 1:2) {
    #THE FOLLOWING SOLUTION WORKS!!!
    DT2[[i]] <- DT[do.call(order,DT[as.character(sorting[[i]])]),]       
}
0 голосов
/ 10 апреля 2019

Вот метод с setorder из data.table

library(data.table)
Map(setorderv, replicate(2, copy(DT), simplify = FALSE), sorting)
#[[1]]
#  avar bvar cvar
#4    1    b    2
#1    1    a    3
#3    3    s    5
#2    4    f    4

#[[2]]
#  avar bvar cvar
#1    1    a    3
#4    1    b    2
#3    3    s    5
#2    4    f    4

Или используйте arrange_at из dplyr (без использования способа оценки)

library(tidyverse)
map(sorting, ~ DT %>%
                 arrange_at(.x))
#[[1]]
#  avar bvar cvar
#1    1    b    2
#2    1    a    3
#3    3    s    5
#4    4    f    4

#[[2]]
#  avar bvar cvar
#1    1    a    3
#2    1    b    2
#3    3    s    5
#4    4    f    4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...