Ответ 1
split
преобразует аргумент f
(второй) в факторы, если он еще не один. Итак, если вы хотите, чтобы заказ был сохранен, поместите столбец самостоятельно с нужным уровнем. То есть:
df$yearmon <- factor(df$yearmon, levels=unique(df$yearmon))
# now split
split(df, df$yearmon)
# $`4_2013`
# Date.of.Inclusion Securities.Included Securities.Excluded yearmon
# 1 2013-04-01 INDUSINDBK SIEMENS 4_2013
# 2 2013-04-01 NMDC WIPRO 4_2013
# $`9_2012`
# Date.of.Inclusion Securities.Included Securities.Excluded yearmon
# 3 2012-09-28 LUPIN SAIL 9_2012
# 4 2012-09-28 ULTRACEMCO STER 9_2012
# $`4_2012`
# Date.of.Inclusion Securities.Included Securities.Excluded yearmon
# 5 2012-04-27 ASIANPAINT RCOM 4_2012
# 6 2012-04-27 BANKBARODA RPOWER 4_2012
Но не используйте split
. Вместо этого используйте data.table
:
Как правило, split
имеет тенденцию быть ужасно медленным по мере увеличения уровней. Итак, я бы предложил использовать data.table
для подмножества в список. Я бы предположил, что это будет намного быстрее!
require(data.table)
dt <- data.table(df)
dt[, grp := .GRP, by = yearmon]
setkey(dt, grp)
o2 <- dt[, list(list(.SD)), by = grp]$V1
Бенчмаркинг по огромным данным:
set.seed(45)
dates <- seq(as.Date("1900-01-01"), as.Date("2013-12-31"), by = "days")
ym <- do.call(paste, c(expand.grid(1:500, 1900:2013), sep="_"))
df <- data.frame(x1 = sample(dates, 1e4, TRUE),
x2 = sample(letters, 1e4, TRUE),
x3 = sample(10, 1e4, TRUE),
yearmon = sample(ym, 1e4, TRUE),
stringsAsFactors=FALSE)
require(data.table)
dt <- data.table(df)
f1 <- function(dt) {
dt[, grp := .GRP, by = yearmon]
setkey(dt, grp)
o1 <- dt[, list(list(.SD)), by=grp]$V1
}
f2 <- function(df) {
df$yearmon <- factor(df$yearmon, levels=unique(df$yearmon))
o2 <- split(df, df$yearmon)
}
require(microbenchmark)
microbenchmark(o1 <- f1(dt), o2 <- f2(df), times = 10)
# Unit: milliseconds
expr min lq median uq max neval
# o1 <- f1(dt) 43.72995 43.85035 45.20087 715.1292 1071.976 10
# o2 <- f2(df) 4485.34205 4916.13633 5210.88376 5763.1667 6912.741 10
Обратите внимание, что решение из o1
будет белым списком. Но вы можете установить имена просто, выполнив names(o1) <- unique(dt$yearmon)