目前我有一个问题如下.在存在每个主题的多个观察的数据集中,我想制作该数据集的子集,其中仅选择记录的最大数据.例如,对于如下数据集:
ID <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
group <- data.frame(Subject=ID, pt=Value, Event=Event)
Run Code Online (Sandbox Code Playgroud)
对象1,2和3的最大pt值分别为5,17和5.我怎么能首先找到每个主题的最大pt值,然后将这个观察结果放在另一个数据框中?这意味着该子集仅具有每个主题的最大pt值.
假设我有一个包含一些棒球运动员的数据表:
library(plyr)
library(data.table)
bdt <- as.data.table(baseball)
Run Code Online (Sandbox Code Playgroud)
对于每个玩家(由id给出),我想找到与他们玩最多游戏的年份相对应的行.这在plyr中很简单:
ddply(baseball, "id", subset, g == max(g))
Run Code Online (Sandbox Code Playgroud)
data.table的等效代码是什么?
我试过了:
setkey(bdt, "id")
bdt[g == max(g)] # only one row
bdt[g == max(g), by = id] # Error: 'by' or 'keyby' is supplied but not j
bdt[, .SD[g == max(g)]] # only one row
Run Code Online (Sandbox Code Playgroud)
这有效:
bdt[, .SD[g == max(g)], by = id]
Run Code Online (Sandbox Code Playgroud)
但它比plyr快30%,这表明它可能不是惯用语.
我曾经用dplyr实现我的数据争论,但有些计算是"慢"的.特别是按组子集,我读到dplyr很慢,当有很多组并且基于这个基准数据时.表可能更快,所以我开始学习data.table.
以下是如何使用250k行和大约230k组重现与我的实际数据接近的内容.我想按id1,id2进行分组,并将max(datetime)每个组的行子集化.
# random datetime generation function by Dirk Eddelbuettel
# https://stackoverflow.com/questions/14720983/efficiently-generate-a-random-sample-of-times-and-dates-between-two-dates
rand.datetime <- function(N, st = "2012/01/01", et = "2015/08/05") {
st <- as.POSIXct(as.Date(st))
et <- as.POSIXct(as.Date(et))
dt <- as.numeric(difftime(et,st,unit="sec"))
ev <- sort(runif(N, 0, dt))
rt <- st + ev
}
set.seed(42)
# Creating 230000 ids couples
ids <- data.frame(id1 = stringi::stri_rand_strings(23e4, 9, pattern = "[0-9]"),
id2 = stringi::stri_rand_strings(23e4, 9, pattern = "[0-9]"))
# Repeating randomly the ids[1:2000, ] to create groups
ids <- …Run Code Online (Sandbox Code Playgroud) 我经常有数据集,我随着时间的推移有多个事件测量,我想在一个月内为每个事件采取最大日期.我这样做是通过创建年份和月份变量,然后按日期降序排序,然后是group_by除日期之外的所有变量,然后使用a slice来获取最大日期.我听到Hadely在视频中说这arrange是一个缓慢的操作.我想知道这样做的有效方法是在整齐的范围内.
请发布base,data.table,其他答案,以便其他用途可以从这个问题中受益,但我的愿望是一个整齐的方法.
library(tidyverse)
set.seed(10)
dat <- data_frame(
date = sample(seq(as.Date('1999/01/01'), as.Date('2001/01/01'), by="day"), 1000, TRUE),
cash = sample(1010:1030, 1000, TRUE),
stage = sample(LETTERS[1:7], 1000, TRUE)
) %>% distinct()
dat %>%
mutate(
year = format(date, '%Y'),
month = format(date, '%B')
) %>%
arrange(desc(date)) %>%
group_by(cash, stage, year, month) %>%
slice(1)
Run Code Online (Sandbox Code Playgroud)