所以我有一个数据框,我想从中抽出第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来执行此操作,但我无法确定如何指定函数中的上一行。实际的数据帧是巨大的,所以任何更整洁的方式都会很棒。
最终我希望该函数也保留具有唯一名称的行,所以如果这可以合并到同一个函数中,我会非常高兴!
提前感谢您的帮助......
答案 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