R选择重复行

3

好的,我对R相当新手,并尝试搜索文档来解决我的问题,以下是我的问题:

我有一个名为heeds.data的数据框架,其形式如下(出于简单起见,省略了一些列) eval.num, eval.count, ... fitness, fitness.mean, green.h.0, green.v.0, offset.0, green.h.1, green.v.1,...green.h.7, green.v.7, offset.7...

我已经选择了一行数据,符合以下条件:

best.fitness <- min(heeds.data$fitness.mean[heeds.data$eval.count >= 10])
best.row <- heeds.data[heeds.data$fitness.mean == best.fitness]

现在,我想要的是所有具有绿色.h.0到offset.7列(连续的一段列)等于best.row的其他行。
我认为这可能有效。
heeds.best <- heeds.data$fitness[
  heeds.data$green.h.0 == best.row$green.h.0 & ...
]

但是使用24列似乎是一种愚蠢的方法。我正在寻找一些更简单、手动输入更少的东西。
以下是一个简短的数据示例,以展示我的需求。
eval.num, eval.count, fitness, fitness.mean, green.h.0, green.v.0, offset.0
1         1           1500     1500          100        120        40
2         2           1000     1250          100        120        40
3         3           1250     1250          100        120        40
4         4           1000     1187.5        100        120        40
5         1           2000     2000          200        100        40
6         1           3000     3000          150        90         10
7         1           2000     2000          90         90         100
8         2           1800     1900          90         90         100

应选择第4行作为“最佳”。 然后,我希望按以下方式获取结果。
eval.num, eval.count, fitness, fitness.mean, green.h.0, green.v.0, offset.0
1         1           1500     1500          100        120        40
2         2           1000     1250          100        120        40
3         3           1250     1250          100        120        40
4         4           1000     1187.5        100        120        40

数据实际上并没有排序,而且还有许多其他列,但这就是概念。

谢谢!


1
你能否编辑你的帖子,以实际显示数据和代码? - Dirk Eddelbuettel
好的,这样怎么样?我希望这能更清楚一些。至于代码,我知道如何选择我想要的最低值,并且我需要代码来获取与该列匹配的某些列的行。 - Matt
2个回答

5
您的问题本质上是一个复杂的索引问题。我有一个解决方案,虽然可能还有更简单的方法。我将您的示例数据加载到了DF中:
首先,这可以为我们获取最佳行索引(使用which.min()很容易):
R> bind <- which.min(DF[,"fitness.mean"])  # index of best row

接下来,我们对一行进行比较(只涉及第5到7个位置的列),使用 apply()函数。

我们使用一个比较函数 cmpfun将当前行 r 与最佳行(由 bind 索引)进行比较,并使用 all()获取所有元素相应的行。 [ 这里需要 drop=FALSE以使它在两侧可比,否则使用 as.numeric()。 ]

R> cmpfun <- function(r) all(r == DF[bind,5:7,drop=FALSE])  # compare to row bind

我们只需按行应用此操作:apply

R> brows <- apply(DF[,5:7], 1, cmpfun)

这些是我们想要的行:

R> DF[brows, ]
  eval.num eval.count fitness fitness.mean green.h.0 green.v.0 offset.0
1        1          1    1500         1500       100       120       40
2        2          2    1000         1250       100       120       40
3        3          3    1250         1250       100       120       40
4        4          4    1000         1188       100       120       40
R> 

使用三列进行比较并不重要 -- 重要的是我们有一个索引表达式(这里是5:7)来获取我们想要的列。


0

这是展示 merge 是一个强大的 R 函数的机会。

使用这些数据:

dat <- read.csv(textConnection('eval.num,eval.count,fitness,fitness.mean,green.h.0,green.v.0,offset.0
1,1,1500,1500,100,120,40,
2,2,1000,1250,100,120,40,
3,3,1250,1250,100,120,40,
4,4,1000,1187.5,100,120,40,
5,1,2000,2000,200,100,40,
6,1,3000,3000,150,90,10,
7,1,2000,2000,90,90,100,
8,2,1800,1900,90,90,100'))

我们进行以下计算:
  imin <- which.min(dat$fitness)                     ## identify min row
  dupcols <- c('green.h.0', 'green.v.0', 'offset.0') ## dup cols for checking
  merge(dat, dat[imin, dupcols], by=dupcols, all=F) 

提供

>   merge(dat, dat[imin, dupcols], by=dupcols, all=F)
  green.h.0 green.v.0 offset.0 eval.num eval.count fitness fitness.mean
1       120        40       NA        1       1500  1500.0          100
2       120        40       NA        2       1000  1250.0          100
3       120        40       NA        3       1250  1250.0          100
4       120        40       NA        4       1000  1187.5          100

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接