gpt4 book ai didi

r - "group by"类似于 R 中的命令,以 min 作为聚合函数和多列

转载 作者:行者123 更新时间:2023-12-01 11:51:07 25 4
gpt4 key购买 nike

我有一个有很多列的框架c1 c2 c3 c4 ... c30 d

我想聚合并找到 c1..30 中唯一的所有行,然后获取该行的 min(d)。在 sql 中,这将是一个由 c1, ..., c30 组成的组。

d 是日期类型。

我在堆栈中找到了一些解决方案,但似乎没有一个适用于 1) 如此多的列 2) 计算 min 而不是求和。

任何输入都会很棒。

最佳答案

这是使用 data.table 的答案包含一些假数据的包:

library(data.table)

DT<-data.table(matrix(sample(1:2,3000,replace=TRUE),ncol=30))
DT2<-DT[sample(seq_len(nrow(DT)),9000,replace=TRUE)]
# EDIT: now "d" is a date.
DT2[,d:=as.POSIXct(origin = "1960-01-01",rnorm(nrow(DT2), sd = 1000))]
setnames(DT2,c(paste0("c",1:30),"d"))

## pick up herewith your own data, starting with the commented next line
# DT2 <- as.data.table(dataset)
setkeyv(DT2,paste0("c",1:30))

DT3<-DT2[,list(minD=min(d)),by=key(DT2)]

dim(DT2)
# [1] 9000 31
dim(DT3)
# [1] 100 31

Matthew 的小补充:

+10,以及漂亮的假数据。首先设置一个 key ,这样你就可以做 by=key(DT)有时会有点繁琐,所以为了简单起见,我通常会为这样的事情做一个临时的。但是,首先尝试最自然的事情:

DT2[,min(d),by=paste0("c",1:30)]
Error in `[.data.table`(DT2, , min(d), by = paste0("c", 1:30)) :
'by' appears to evaluate to column names but isn't c() or key(). Use by=
list(...) if you can. Otherwise, by=eval(paste0("c", 1:30)) should work.
This is for efficiency so data.table can detect which columns are needed.

错误信息告诉我们需要做什么:

ans = DT2[,min(d),by=eval(paste0("c",1:30))]
dim(ans)
[1] 100 31

下一个自然的想法当然是:好吧,如果 data.table 足够聪明,知道 by是列名并将其放在错误消息中,为什么不能这样做呢?答案是它只是根据数据进行猜测。在某些边缘情况下,它不是很清楚。所以目前需要用户的额外意图:用 eval 包装.不过,我对此并不完全满意,所以也许我们可以改进这一点。

编辑:重命名新的 data.table

在我的方法中,我将新列命名为 minD当我通过输入

创建它时
DT3<-DT2[,list(minD=min(d)),by=key(DT2)]

使用 Matthew Dowle 的方法,您可以通过输入以几乎相同的方式实现此目的

ans = DT2[,list(minD=min(d)),by=eval(paste0("c",1:30))]

如果您已经创建了该列并想重命名它,请使用 setnames如下:

setnames(DT3,old="minD",new="theNewMinD")

这避免了复制整个 data.table并在分配时保留内存(使用 names(DT3)<-"something" 时这两个优点都会丢失),如 ?setnames 下的文档中所述

关于r - "group by"类似于 R 中的命令,以 min 作为聚合函数和多列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11349741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com