1

所以我有一个数据框,我想从中提取第 2 列中具有相同名称的行。对于每组具有相同名称的重复行,我只想保留具有最高值的行,如果它的分数比其他副本高 2。所以在这个例子中,我想保留第 2 行而不是第 5 行。

>df <- data.frame(score=c(1,5,1,3,3),name=c("A1","A1","A2","A3","A3"))
>df
score name
 1    A1
 5    A1
 1    A2
 3    A3
 3    A3

我几乎可以用 for 循环做我想做的事情,并制作一个“dup”与“keep”的小矩阵,然后用来拉出满足这两个条件的数据帧的行。

>test <- matrix(ncol=1,nrow=nrow(df))
>for(i in 1:nrow(df)){ifelse((df[i,"name"] == df[i-1,"name"]) && (df[i,"score"] >= (df[i-1,"score"] + 2)),test[i] <- "keep",test[i] <- "dup")}
> test
     [,1]  
[1,] NA    
[2,] "keep"
[3,] "dup" 
[4,] "dup" 
[5,] "dup"
>df[which(test[,1] == "keep"),]
    score name
2     5   A1

哪个有效(除了第一个),但显然是丑陋和缓慢的地狱。我知道必须有一种方法可以使用某些版本的 apply 来执行此操作,但我无法弄清楚如何指定函数中的前一行。实际的数据框很大,所以任何更整洁的方式都会很棒。

最终,我希望该函数也保留具有唯一名称的行,因此如果可以将其合并到同一个函数中,我会非常高兴!

提前感谢您的帮助....

4

2 回答 2

1

那这个呢 ?

x <- df[order(df$name),]
x$diff <- ave(x$score, x$name, FUN=function(x) c(NA,diff(x)))
x[duplicated(x$name) & x$diff > 2,]
 score name diff
2     5   A1    4

编辑

以前的解决方案是错误的,这里是正确的(我希望)。我按名称对元素进行分组,并且只保留具有特定条件的行(类似于异常值)

df <- data.frame(score=c(1,5,1,3,3,6,6),name=c("A1","A1","A2","A3","A3","A2","A1"))
by(df$score, df$name, FUN=function(x)
  if(max(x) > 2*max(x[-which.max(x)]))
     max(x)

df$name: A1
[1] NA
------------------------------------------------------------------------------------------------ 
df$name: A2
[1] 6
------------------------------------------------------------------------------------------------ 
df$name: A3
[1] NA
       else NA)
于 2013-06-17T11:25:09.910 回答
0

尝试这个:

   
> 聚合(分数~名称,数据=df,最大值)
   名字分数
1 A1 5
2 A2 1
3 A3 3
于 2013-07-29T19:18:07.230 回答