df <- data.frame(group=c(1,2,4,2,1,4,2,3,3),
ts=c("2014-02-13","2014-06-01","2014-02-14","2014-02-11","2013-02-01","2014-02-02","2014-03-21","2014-12-01","2014-02-11"),
letter=letters[1:9])
df$ts <- as.Date(df$ts,format='%Y-%m-%d')
我想找到一个操作,它将产生包含每组最小时间戳的完整行,在这种情况下,
group ts letter
1 2013-02-01 e
4 2014-02-02 f
2 2014-02-11 d
3 2014-02-11 i
快速而肮脏(和缓慢)的基础R解决方案
dfo <- data.frame(df[order(df$ts,decreasing=F),],index=seq(1:nrow(df)))
mins <- tapply(dfo$index,dfo$group,min)
dfo[dfo$index %in% mins,]
直观地说,我认为如果有一种方法可以按组添加订单索引,那么我可以过滤到该列的值为1的位置,但我不确定如何在没有批次的情况下执行它子集化和重新加入。
答案 0 :(得分:3)
您可以使用dplyr
library(dplyr)
group_by(df, group) %>% summarise(min = min(ts), letter = letter[which.min(ts)])
# group min letter
# 1 1 2013-02-01 e
# 2 2 2014-02-11 d
# 3 3 2014-02-11 i
# 4 4 2014-02-02 f
您还可以slice
排名的行
group_by(df, group) %>%
mutate(rank = row_number(ts)) %>%
arrange(rank) %>%
slice(1)
答案 1 :(得分:3)
这是一个data.table解决方案。您似乎希望ts
而不是group
的结果订单。就是这样。
library(data.table)
setDT(df)[,.SD[which.min(ts)],by=group][order(ts)]
# group ts letter
# 1: 1 2013-02-01 e
# 2: 4 2014-02-02 f
# 3: 2 2014-02-11 d
# 4: 3 2014-02-11 i
答案 2 :(得分:0)
这里是使用基础R的单行。
df[sapply(split(df,df$group), function(x) row.names(x)[which.min(x$ts)] ),]
打破一些:
list.by.group <- split(df,df$group)
#a vector of the row names corresponding to the earliest date in each group
names.of.which.min <- sapply(list.by.group, function(x) row.names(x)[which.min(x$ts)])
#subset the data frame by row name
df[names.of.which.min,]