统计数据框中相似行的出现次数(使用R语言)

3

我有一个名为DF的数据,格式如下(这只是一个简化的示例):

eval.num, eval.count, fitness, fitness.mean, green.h.0, green.v.0, offset.0 random
1         1           1500     1500          100        120        40       232342
2         2           1000     1250          100        120        40       11843
3         3           1250     1250          100        120        40       981340234
4         4           1000     1187.5        100        120        40       4363453
5         1           2000     2000          200        100        40       345902
6         1           3000     3000          150        90         10       943
7         1           2000     2000          90         90         100      9304358
8         2           1800     1900          90         90         100      284333

然而,eval.count列是不正确的,我需要修复它。它应该报告具有相同值 (green.h.0、green.v.0 和 offset.0) 的行的数量,仅查看前面的行。
上面的示例使用了预期值,但假设它们是不正确的。
如何添加一个新列(比如"count"),它将计算所有先前具有指定变量相同值的行?
我已经得到了类似问题的帮助,只需选择具有特定列相同值的所有行,所以我认为我可以在其周围编写一个循环,但我觉得这样效率低下。

做一次很慢,而且我有8000行,所以我认为这是不可行的。我希望有更有效的方法来完成它。 - Matt
3个回答

9

好的,首先我们来看一个简单的情况,即只有一列。

> data <- rep(sample(1000, 5),
              sample(5, 5))
> head(data)
[1] 435 435 435 278 278 278

然后你可以使用rle来确定连续的序列:
> sequence(rle(data)$lengths)
[1] 1 2 3 1 2 3 4 5 1 2 3 4 1 2 1

或完全:

> head(cbind(data, sequence(rle(data)$lengths)))
[1,]  435 1
[2,]  435 2
[3,]  435 3
[4,]  278 1
[5,]  278 2
[6,]  278 3

对于你的多列情况,可能有很多种方法来应用这个解决方案。最简单的方法可能是将你关心的列粘贴在一起形成一个单一的向量。


1

好的,我使用了我在另一个问题上得到的答案,并想出了一个循环,我认为它会起作用。这就是我要使用的:

cmpfun2 <- function(r) {
    count <- 0
    if (r[1] > 1)
    {
        for (row in 1:(r[1]-1))
        {
            if(all(r[27:51] == DF[row,27:51,drop=FALSE]))  # compare to row bind
            {
                count <- count + 1
            }
        }
    }
    return (count)
}
brows <- apply(DF[], 1, cmpfun2)
print(brows)

请评论一下,如果我犯了错误并且这不起作用,但我认为我已经弄清楚了。谢谢!

你的解决方案看起来还不错,但如果我是你,我至少会尝试理解上面Jonathan的答案。相比循环和索引操作,RLE通常是更快且更可靠的替代方案。 - Leo Alekseyev

0

我有一个解决方案,是我随着时间推移逐渐想出来的(很抱歉我有一段时间没有检查过这个)

checkIt <- function(bind) {

    print(bind)

    cmpfun <- function(r) {all(r == heeds.data[bind,23:47,drop=FALSE])}
    brows <- apply(heeds.data[,23:47], 1, cmpfun)

    #print(heeds.data[brows,c("eval.num","fitness","green.h.1","green.h.2","green.v.5")])
    print(nrow(heeds.data[brows,c("eval.num","fitness","green.h.1","green.h.2","green.v.5")]))
}

请注意,heeds.data是我的实际数据框架,我最初只打印了几列以确保它正常工作(现在已注释掉)。另外,23:47是需要检查重复的部分。
此外,我真的没有学习到足够的R知识,所以我很乐意听取建议。
希望这可以帮助!

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