Функция R для заказа data.frames, хранящихся в объекте списка - PullRequest
2 голосов
/ 23 марта 2020

Я пытаюсь найти элегантную функцию для упорядочивания data.frames, содержащихся в объекте списка. Я уже знаю, что lapply (df, function (x) x [with (x, order (var)),]) работает нормально, но это кажется слишком сложным. Я пытаюсь использовать функцию «[», которая прекрасно работает, если я ввожу номера строк вручную. Но я бы хотел использовать номера строк, сгенерированные функцией порядка, очевидно.

df <- list(
    data.frame(name = c("John", "Paul", "George", "Ringo"),   height = c(60, 58, 65, 55)),
    data.frame(name = c("Frank", "Tony", "Arthur", "Edward"), height = c(55, 65, 60, 50))
)

lapply(df, "[", c("height", "name"))

lapply(df, "[", c(3:1), )

order <- lapply(df, with, order(name))

order

lapply(df, with, order(name), "[")

lapply(df, with, "[", order(name), )

lapply(df, "[", with, order(name), )

Map("[", order , , df)

Ответы [ 4 ]

4 голосов
/ 02 апреля 2020

Если вы используете library(data.table) вместо data.frame, то решение будет довольно элегантным.

Мы можем преобразовать ваш объект в data.table, используя lapply(df, setDT). Обратите внимание, что этот шаг не понадобится, если вы сначала создадите свои объекты как data.table, что будет более типичным рабочим процессом.

Тогда заказ можно сделать с помощью

lapply(df, setkey, 'name')

# [[1]]
#      name height
# 1: George     65
# 2:   John     60
# 3:   Paul     58
# 4:  Ringo     55
# 
# [[2]]
#      name height
# 1: Arthur     60
# 2: Edward     50
# 3:  Frank     55
# 4:   Tony     65
3 голосов
/ 05 апреля 2020

Другие пакеты упростили бы это. Если вы хотите использовать базу, вы можете расширить то, что пытались сделать, с помощью Map():

order <- lapply(df, with, order(name))
Map("[", df, order, TRUE)
#pseudo translation: df[order, TRUE]
## where TRUE will repeat and select all columns of df

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

lapply(df, function(x) x[order(x[["name"]]), ])

#or
fx_reorder = function (x, col){
  x[order(x[[col]]), ]
}

lapply(df, fx_reorder, "name")

## or to accept multiple columns
fx_reorder2 = function(x, cols) {
  if (missing(cols)) cols = names(x)
  x[do.call("order", x[cols]), ]
}

lapply(df, fx_reorder2)
lapply(df, fx_reorder2, "name")
lapply(df, fx_reorder2, 1:2)

2 голосов
/ 23 марта 2020

Мы можем использовать arrange с map

library(dplyr)
library(purrr)
map(df,  ~ .x %>% 
              arrange(name))
0 голосов
/ 04 апреля 2020

Вы знакомы с пакетом dplyr? Вы можете поместить функцию arrange в lapply.

lapply(df, arrange, -height)

Если вы не знакомы с dplyr, я бы посмотрел на нее. Похоже, что ваша проблема может быть решена с bind_rows и group_by.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...