我有一个有很多列 c1 c2 c3 c4 ... c30 d 的框架
我想聚合并找到 c1..30 中唯一的所有行,然后获取该行的 min(d) 。在 sql 中,这将是由 c1、...、c30 组成的组。
d 是日期类型。
我在堆栈中找到了一些解决方案,但似乎没有一个适用于 1)这么多列 2)做一个 min 而不是 sum。
任何输入都会很棒。
我有一个有很多列 c1 c2 c3 c4 ... c30 d 的框架
我想聚合并找到 c1..30 中唯一的所有行,然后获取该行的 min(d) 。在 sql 中,这将是由 c1、...、c30 组成的组。
d 是日期类型。
我在堆栈中找到了一些解决方案,但似乎没有一个适用于 1)这么多列 2)做一个 min 而不是 sum。
任何输入都会很棒。
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
马修的小补充:
+10,以及漂亮的假数据。首先设置一个键以便你可以做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
未经测试,没有最小的可重现示例:
apply(unique(dataset), 1, min)
分解它:
x <- unique(dataset) #finds only unique rows
apply(x, 1, min) # applies min across rows
# replace the 1 with a 2 and it applies across columns