3

给定一个包含 ID 列、值列和日期列的数据框,我想执行以下操作:对于每个 ID(按 ID 分组)返回具有最高值的行的日期。

> df <- data.frame(ID=c(101, 101, 101, 202), Date=c("2013-04-12", "2013-06-21", "2013-07-06", "2013-07-06"), Value=c(3.4, 5.8, 4.2, 2.1))
> df
   ID       Date Value
1 101 2013-04-12   3.4
2 101 2013-06-21   5.8
3 101 2013-07-06   4.2
4 202 2013-07-06   2.1

对于上述数据框,输出应类似于:

   ID       Date
1 101 2013-06-21 # because it has highest Value for ID=101 (i.e., 5.8)
2 202 2013-07-06 # bacause it has highest Value for ID=202 (2.1)

我知道使用 aggregate() 通过 ID 获取最大值,但是如何返回 Date 列而不是实际聚合的 max() 值?

4

3 回答 3

3

如果您的数据集很大,这是一种data.table方法:

library(data.table)
df <- data.table(df)
df[ , Date[which.max(Value)], by=ID]
    ID         V1
1: 101 2013-06-21
2: 202 2013-07-06

如果您的数据大小适中并且您没有太多 ID 值(我猜 > 100 - 500),那么您也可以这样做:

sapply(X=split(df, df$ID),
       FUN=function (k) k$Date[which.max(k$Value)])
       101        202 
2013-06-21 2013-07-06 
于 2013-07-16T21:53:37.200 回答
2

当您想将函数应用于由另一列索引的一列时,tapply最好的选择是。

tapply(df[,2],df[,1],max)

tapply返回一个向量或一个列表,因此有时需要一些后处理。

编辑:哎呀,误读了。因此,您有一列要value根据索引获取 的最大值ID,但您真的想要最大值的日期吗?

这有点复杂,最好用orderand解决duplicated。第一个将对数据进行排序,使每个用户中的最高值首先出现,然后duplicated可用于删除额外的观察值。

ind = order(df$ID,df$Value,decreasing=TRUE)
df = df[ind,]
df[!duplicated(df$ID),]

这有点倒退,但我认为它会起作用

于 2013-07-16T21:33:53.197 回答
1

我能找到的最简单的方法是使用库(sqldf),在 R 中说 SQL。

> library(sqldf)
> sqldf('select * from df group by ID having Value = max(Value)')
    ID     Date    Value
 1 101 2013-06-21   5.8
 2 202 2013-07-06   2.1

在 mac 中安装 sqldf 有点棘手。无论如何,在 R 中讲 SQL 会使事情变得容易得多。以下是我的程序:

  install.packages("sqldf")
  options(gsubfn.engine = "R")
  packageVersion("gsubfn")
  library(RSQLite.extfuns)
  library(DBI)
  library(RSQLite)
  library(proto)
  library(gsubfn)
  library(sqldf)
于 2014-04-12T03:08:06.470 回答