我有一个数据框,叫它A,看起来像这样:
GroupID Dist1 Dist2 ...
1 4 4
1 5 4
1 3 16
2 0 4
2 7 2
2 8 0
2 6 4
2 7 4
2 8 2
3 7 4
3 5 6
...
Run Code Online (Sandbox Code Playgroud)
GroupID是一个因子,Dist1,Dist2是整数.
我有一个派生数据框,SummaryA
GroupID AveD1 AveD2 ...
1 4 8
2 6 2
3 6 5
...
Run Code Online (Sandbox Code Playgroud)
对于每个groupID,我需要找到具有最小值的ROW NUMBER,进行进一步操作,并将数据提取到我的摘要集.例如,我需要:
GroupID MinRowD1
1 1
2 4
3 11
Run Code Online (Sandbox Code Playgroud)
在比赛中,我选择哪个并不重要,但我不知道如何得到这个.我不能使用which(),因为它不能很好地操作因素,我不能使用ave(Fun = min),因为我需要的是位置,而不是最小值.如果我做的事情与每组的最小匹配,我可以有多个匹配,这搞砸了.
有关如何做到这一点的任何建议?
使用by和rownames您的数据
> dat$row <- 1:nrow(dat)
> by(dat,dat$GroupID,FUN = function(x) rownames(x)[which.min(x$Dist1)])
dat$GroupID: 1
[1] "3"
----------------------------------------------------------------------------------------
dat$GroupID: 2
[1] "4"
----------------------------------------------------------------------------------------
dat$GroupID: 3
[1] "11"
Run Code Online (Sandbox Code Playgroud)
在这里我假设dat
dat <- read.table(text = 'GroupID Dist1 Dist2
1 4 4
1 5 4
1 3 16
2 0 4
2 7 2
2 8 0
2 6 4
2 7 4
2 8 2
3 7 4
3 5 6', header = T)
Run Code Online (Sandbox Code Playgroud)
编辑使用data.table包的另一种解决方案
我认为data.table提供了更优雅的解决方案:
library(data.table)
dat$row <- 1:nrow(dat)
dtb <- as.data.table (dat)
dtb [,.SD[which.min(Dist1)],by=c('GroupID')]
GroupID Dist1 Dist2 row
1: 1 3 16 3
2: 2 0 4 4
3: 3 5 6 11
Run Code Online (Sandbox Code Playgroud)
Edit1行表而不创建行列(@Arun注释)
dtb[, {i = which.min(Dist1); list(Dist1=Dist1[i],
Dist2=Dist2[i], rowNew=.I[i])}, by=GroupID]
GroupID Dist1 Dist2 rowNew
1: 1 3 16 3
2: 2 0 4 4
3: 3 5 6 11
Run Code Online (Sandbox Code Playgroud)
这是一个基础R解决方案; 基本思想是按GroupID拆分数据,获取每个行的最小值,然后将其重新组合在一起.有些人认为这些plyr功能是更直观的方式; 我肯定很快会出现使用其中一个的解决方案......
A$row <- 1:nrow(A)
As <- split(A, A$GroupID)
sapply(As, function(Ai) {Ai$row[which.min(Ai$Dist1)]})
Run Code Online (Sandbox Code Playgroud)
对于大型数据集,split在标量上执行时更快,而不是像这样的数据帧.
rows <- split(1:nrow(A), A$GroupID)
sapply(rows, function(rowi) {rowi[which.min(A$Dist1[rowi])]})
Run Code Online (Sandbox Code Playgroud)