如何在R中找到每个因子的最小行数?

Dav*_*eim 1 r dataframe

我有一个数据框,叫它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),因为我需要的是位置,而不是最小值.如果我做的事情与每组的最小匹配,我可以有多个匹配,这搞砸了.

有关如何做到这一点的任何建议?

ags*_*udy 7

使用byrownames您的数据

> 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)


Aar*_*ica 5

这是一个基础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)

  • 我在理论上喜欢这个,但拆分需要很长时间才能得到32,000个因子值. (3认同)