R - 使用apply来比较之前的行

时间:2013-06-17 10:58:24

标签: r apply

所以我有一个数据框,我想从中抽出第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来执行此操作,但我无法确定如何指定函数中的上一行。实际的数据帧是巨大的,所以任何更整洁的方式都会很棒。

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

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

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

试试这个:

   
> aggregate(score~name, data=df, max)
   name score
1   A1     5
2   A2     1
3   A3     3