按最大

时间:2016-08-01 12:20:37

标签: r

我有data frame,(我只显示df的尾部)此数据框名为conv2

8464   208394_x_at                   ESM1                          -1.035878e-01
8468   200858_s_at                SNORD55                          -1.034971e-01
8469   200858_s_at               SNORD38B                          -1.034971e-01
8467   200858_s_at                   RPS8                          -1.034971e-01
8472     207381_at                   RPS8                          -1.034510e-01
8477   211197_s_at                 ICOSLG                          -1.033752e-01

我想要的是,只要在第二列中重复了一个名称,例如RPS8,就删除所有包含此名称的行,除了第三列的absoulte值最高的行。因此,在示例中,行8467将被删除。

我这样做了

for (d in dup){

  conv2 <- rbind(conv2, conv[which(conv$SYMBOL == d),][which.max(abs(conv[which(conv$SYMBOL == d),][,3])),])

}

有更好更快的方法吗?

3 个答案:

答案 0 :(得分:4)

我们可以使用

library(dplyr)
conv2 %>%
    group_by(col1, col2) %>%
    slice(which.max(abs(col3)))

更快的选择是

conv2 %>%
   group_by(col1, col2) %>%
   arrange(desc(abs(col3))) %>%
   slice(1)  

或者我们可以使用data.table

library(data.table)
setDT(conv2)[order(-abs(col3)),  .SD[1L], .(col1, col2)]

注意:应更改列名称(因为示例中未显示)

答案 1 :(得分:2)

以下是使用“split-apply-combine”方法的基础R解决方案。

# split data.frame by column 2
myList <- split(conv2, conv2$col2)

# loop through list of data.frames and rbind observations with maximum values
dfNew <- do.call(rbind, lapply(myList, function(i) i[which.max(abs(i$col3)),]))

答案 2 :(得分:0)

如果你想使用for循环执行相同的逻辑,你可以尝试这种方式,但是之前的OP已经显示了一种简单的方法,而不是使用for循环

df1 <- data.frame(col1 = NA, col2 = NA, col3 = NA)
for(i in unique(df$col2)){
  x <- max(df$col3[df$col2==i])
df12 <- unique(df[df$col3==x & df$col2==i,])
df1 <- rbind(df1,print(df12))
df1 <- df1[!is.na(df1$col1),]
}
print(df1)
     col1     col2      col3
2  208394_x_at     ESM1 -1.035878
21 200858_s_at  SNORD55 -1.034971
3  200858_s_at SNORD38B -1.034971
5    207381_at     RPS8 -1.034510
6  211197_s_at   ICOSLG -1.033752

数据

df <- data.frame(col1 =c("208394_x_at","200858_s_at","200858_s_at","200858_s_at","207381_at","211197_s_at"),
  col2 = c("ESM1","SNORD55","SNORD38B","RPS8","RPS8","ICOSLG"),
  col3 = c(-1.035878,-1.034971,-1.034971,-1.034971,-1.034510,-1.033752),stringsAsFactors=F)