【问题标题】:R: remove row if certain value can be found in other rowR:如果可以在其他行中找到某个值,则删除行
【发布时间】:2017-10-21 20:02:42
【问题描述】:

我使用一个数据集,如果标签为 1,并且有一个标签为 3 的 ID 号,我想删除一行。编辑:标签值只能是:NA、1、2 或 3。ID 号是不同的,如果存在标签 1、标签 2 和标签 3,则只能找到 3 次。

> dat1 = data.frame(id=c(15399,15404,15405,15407,15407,15407,15403), tag=c(NA,NA,1,1,2,3,1))

> dat1 id tag 1 15399 NA 2 15404 NA 3 15405 1 4 15407 1 5 15407 2 6 15407 3 7 15403 1

我需要退货:

> dat1 id tag 1 15399 NA 2 15404 NA 3 15405 1 5 15407 2 6 15407 3 7 15403 1

有人可以帮我吗?我只知道如何删除标签为 3 的所有 ID:

> subset(dat1,!dat1$id %in% dat1$id[dat1$tag == 3]) id tag 1 15399 NA 2 15404 NA 3 15405 1 7 15403 1

【问题讨论】:

  • dat2 <- dat1[dat1$tag!="1",] 为什么不这样呢? (为此,您必须避免/更改 NA 值)
  • 正在尝试从数据框中删除重复的行?
  • @jyr 这也将删除我想保留的第 3 行。如果存在与标签 3 具有相同 ID 号的行,我只想删除包含标签 1 的行。
  • @BidishaPyne 以某种方式是的:如果有一个带有标签 1 的 id 和另一个带有标签 3 的 id,我只对使用该 id 号保留标签 3 感兴趣。
  • @akrun 感谢您的关注。我将编辑帖子。

标签: r conditional row subset


【解决方案1】:
dat1[!duplicated(dat1$id,fromLast = TRUE)|duplicated(dat1$id)&dat1$tag!="1",]

您可以像这样简单地做到这一点,但首先您需要按标签对数据进行排序。它不是很漂亮,但它应该可以工作。

> dat1[!duplicated(dat1$id,fromLast = TRUE)|duplicated(dat1$id)&dat1$tag!="1",]
     id tag
1 15399  NA
2 15404  NA
3 15405   1
5 15407   2
6 15407   3
7 15403   1

【讨论】:

  • 谢谢!这行得通。我需要按标签订购数据是什么意思?因为它似乎与 dat1 一起工作得很好,这不是按标签排序的。还是函数duplicated 已经这样做了?
  • duplicated() 遍历向量并在元素已经出现在向量中时返回 TRUE/FALSE。所以duplicated(c(1,1,2,3,2)) 将返回 FALSE、TRUE、FALSE、FALSE、TRUE。使用参数fromLast=TRUE,它将从末尾开始,并将返回 TRUE FALSE TRUE FALSE FALSE。编辑:过滤器表示所有不重复的内容以及所有内容但没有标签 1。它的顺序敏感,如果您只有标签 1 重复,它可能会出现问题。
【解决方案2】:

我们可以通过data.table 做到这一点

library(data.table)
setDT(dat1)[, .SD[any(tag != 1) & tag !=1 | all(tag==1) |is.na(tag)] , by = id]
#      id tag
#1: 15399  NA
#2: 15404  NA
#3: 15405   1
#4: 15407   2
#5: 15407   3
#6: 15403   1

如果条件是删除 'tag' 为 1 的行,其中还有一个特定 'id' 的 'tag' 3,则

setDT(dat1)[, .SD[!(all(c(1,3) %in% tag) & tag == 1)]  , id]
#      id tag
#1: 15399  NA
#2: 15404  NA
#3: 15405   1
#4: 15407   2
#5: 15407   3
#6: 15403   1

dplyr

library(dplyr)
dat1 %>% 
   group_by(id) %>%
   filter(any(tag != 1) & tag !=1 | all(tag==1) |is.na(tag))

基于第二个条件

dat1 %>%
    group_by(id) %>%
    filter(!(all(c(1,3) %in% tag) & tag ==1))
# A tibble: 6 x 2
# Groups: id [5]
#     id   tag
#  <dbl> <dbl>
#1 15399    NA
#2 15404    NA
#3 15405     1
#4 15407     2
#5 15407     3
#6 15403     1

【讨论】:

  • 这仅删除了 dat1 中的第 3 行,但我想删除第 4 行(与第 6 行的标签 3 共享相同的 ID)
【解决方案3】:
 dat1 = data.frame(id=c(15399,15404,15405,15407,15407,15407,15403), 
 tag=c(NA,NA,1,1,2,3,1))#construct the data
 dat1_tag3<-dat1[dat1$tag==3,]#keep the rows with tag equals to 3
 dat1_tag3<-dat1_tag3[!is.na(dat1_tag3$id),]#remove NA's
 dat2remove<-dat1[(dat1$id %in% unique(dat1_tag3$id) & dat1$tag==1),]#find rows that need to be excluded

 all<-rbind(dat1,dat2remove)#rbinding the two datasets
 all<-all[!(duplicated(all[c("id","tag")]) | duplicated(all[c("id","tag")], fromLast = TRUE)),]#removing duplicates (as pairs)

    id tag
1 15399  NA
2 15404  NA
3 15405   1
5 15407   2
6 15407   3
7 15403   1

【讨论】:

  • 如果你喜欢上传。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 2013-10-10
  • 2023-03-03
  • 1970-01-01
  • 2018-10-06
相关资源
最近更新 更多