split
将始终按字典顺序排序分组。在某些情况下,人们宁愿保留自然秩序。一个人总是可以实现手动滚动功能,但有一个基本的R解决方案吗?
输入:
Date.of.Inclusion Securities.Included Securities.Excluded yearmon
1 2013-04-01 INDUSINDBK SIEMENS 4 2013
2 2013-04-01 NMDC WIPRO 4 2013
3 2012-09-28 LUPIN SAIL 9 2012
4 2012-09-28 ULTRACEMCO STER 9 2012
5 2012-04-27 ASIANPAINT RCOM 4 2012
6 2012-04-27 BANKBARODA RPOWER 4 2012
split
输出:
R> split(nifty.dat, nifty.dat$yearmon)
$`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
$`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
请注意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
感谢。
PS:我知道有更好的方法来创建yearmon
以保留该订单,但我正在寻找通用解决方案。
答案 0 :(得分:18)
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)