简体   繁体   English

根据第二列条件删除重复项

[英]Remove duplicates based on 2nd column condition

I am trying to remove duplicate rows from a data frame based on the max value on a different column我正在尝试根据不同列上的最大值从数据框中删除重复的行

So, for the data frame:因此,对于数据框:

df<-data.frame (rbind(c("a",2,3),c("a",3,4),c("a",3,5),c("b",1,3),c("b",2,6),c("r",4,5))
  colnames(df)<-c("id","val1","val2")

id val1 val2

  a    2    3

  a    3    4

  a    3    5

  b    1    3

  b    2    6

  r    4    5

I would like to keep remove all duplicates by id with the condition that for the corresponding rows they do not have the maximum value for val2.我想通过 id 删除所有重复项,条件是对于相应的行,它们没有 val2 的最大值。

Thus the data frame should become:因此数据框应该变成:

  a    3    5

  b    2    6

  r    4    5

-> remove all a duplicates but keep row with the max value for df$val2 for subset(df, df$id=="a") -> 删除所有重复项,但保留 df$val2 的最大值为subset(df, df$id=="a") 的行

Using base R .使用base R Here, the columns are factors .这里,列是factors Make sure to convert it to numeric确保将其转换为numeric

 df$val2 <- as.numeric(as.character(df$val2))
 df[with(df, ave(val2, id, FUN=max)==val2),]
 #  id val1 val2
 #3  a    3    5
 #5  b    2    6
 #6  r    4    5

Or using dplyr或者使用dplyr

 library(dplyr)
 df %>% 
    group_by(id) %>% 
    filter(val2==max(val2))
 #   id val1 val2
 #1  a    3    5
 #2  b    2    6
 #3  r    4    5

One possible way is to use data.table一种可能的方法是使用data.table

library(data.table)
setDT(df)[, .SD[which.max(val2)], by = id]
##    id val1 val2
## 1:  a    3    5
## 2:  b    2    6
## 3:  r    4    5

Here's how I hope your data is really set up这是我希望您的数据真正设置的方式

df <- data.frame (id = c(rep("a", 3), rep("b", 2), "r"),
                  val1 = c(2, 3, 3, 1, 2, 4), val2 = c(3, 4, 5, 3, 6, 5))

You could do a split - unsplit你可以做一个split - unsplit split

> unsplit(lapply(split(df, df$id), function(x) {
      if(nrow(x) > 1) {
          x[duplicated(x$id) & x$val2 == max(x$val2),]
      } else {
          x
      }
  }), levels(df$id))
#   id val1 val2
# 3  a    3    5
# 5  b    2    6
# 6  r    4    5

You can also use Reduce(rbind, ...) or do.call(rbind, ...) in place of unsplit您还可以使用Reduce(rbind, ...)do.call(rbind, ...)代替unsplit

Another one另一个

df %>% group_by(id) %>%
         slice(which.max(val2))

  id   val1  val2
   a    3     5
   b    2     6
   r    4     5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM