R 删除具有条件的行

R 删除具有条件的行,r,filter,duplicates,conditional-statements,R,Filter,Duplicates,Conditional Statements,我有一个重复ID的数据框,我想删除ID列中的重复项,这样每个人只出现一次。但我想删除那些遵循规则的。有一列抗体。这些患者本可以测试: 总是积极的 总是消极的 先正后负 先负后正 我的兴趣是想知道他们是否检测过阳性。因此,我希望按照以下规则,每个ID只保留一个值: 如果测试结果始终为阳性(仅保留1,随机正值) 如果测试结果始终为负值(仅保留1,随机负值) 如果测试为阳性,然后为阴性(仅保留1,随机正值) 如果测试结果为负值,然后为正值(仅保留1,随机正值) 非常重要的是,选定的ID将其原始

我有一个重复ID的数据框,我想删除ID列中的重复项,这样每个人只出现一次。但我想删除那些遵循规则的。有一列抗体。这些患者本可以测试:

  • 总是积极的

  • 总是消极的

  • 先正后负

  • 先负后正

我的兴趣是想知道他们是否检测过阳性。因此,我希望按照以下规则,每个ID只保留一个值:

  • 如果测试结果始终为阳性(仅保留1,随机正值)

  • 如果测试结果始终为负值(仅保留1,随机负值)

  • 如果测试为阳性,然后为阴性(仅保留1,随机正值)

  • 如果测试结果为负值,然后为正值(仅保留1,随机正值)

非常重要的是,选定的ID将其原始值保留在行中这是:如果对于ID3,在第10行中选择正值,则AA和BB的值应分别为568和45645。因为了解哪种AA或BB值与抗体阳性或阴性状态相关非常重要

下面的评论建议使用

df %>% 
  group_by(ID) %>% 
  summarise(antibodies = ifelse(any(antibodies == "positive"),
                                "positive",
                                "negative"),
            AA = first(AA),
            BB = first(BB))
但这带来了正值不总是在第一行的风险,因此在某些情况下,我可以选择负值AA和BB,并将其与正值关联

我用以下示例来说明我的文本:


df下面是一些您可以在Base-R中探索的代码

new_df <- data.frame(PatientID = unique(old_df$PatientID))
new_df$antibodies <- sapply(split(old_df$antibodies,old_df$PatientID), function(x) any(x=="positive"))

这个例子中的数据很容易复制,我认为下面的例子就涵盖了它。作为解决方案,我使用dplyr包中的
groupby()
将数据汇总到每个唯一ID的一条记录中。使用
ifelse()
语句,我们可以检查原始记录中的是否有任何为正值-在这种情况下,最终值也是正值。如果不是这样,则最终值必须为负值

library(dplyr)
df <- data.frame(ID = c(1,1,1,1,2,2,2,2,3,3,3,3),
                 antibodies = c("positive","positive","positive","positive",
                                "negative","negative","negative","negative",
                                "positive","positive","negative","negative"),
                 stringsAsFactors = F)

df %>% 
  group_by(ID) %>% 
  summarise(antibodies = ifelse(any(antibodies == "positive"),
                                "positive",
                                "negative"))
这将提供以下输出:

     ID antibodies    AA    BB
  <dbl> <chr>      <dbl> <dbl>
1     1 positive     123  3453
2     2 negative    8679    78
3     3 positive     568 45645
ID抗体AA-BB
1正123 3453
2负8679 78
3 3正568 45645

您可以使用
订单
副本

df <- df[order(df$ID, -xtfrm(df$antibodies)),]
#df <- df[order(-xtfrm(df$antibodies)),] #Alternative if ID order not important
df[!duplicated(df$ID),]
#  ID antibodies   AA   BB
#1  1   positive  123 3453
#5  2   negative 8679   78
#9  3   positive  567  786

亲爱的@pieterbons,非常感谢您的简单代码!它很好吃!但是,我希望保留额外的行,就像在示例中一样,我不介意保留在其他行中的值,但我需要它们。我怎样才能欺骗代码呢谢谢您希望保留AA和BB的哪些值(因为ID==1有多个)?是的。真的有!唯一的问题是,如果为ID1保存了第2行,那么我也希望保存AA和BB第2行。我不确定这是否有意义它是否有效!真的很感激!:)谢谢谢谢!!这很有效!!!我能问一下-xtfrm的用途吗?谢谢@GKiThat只需要在它前面放置一个
-
     ID antibodies
  <dbl> <chr>     
1     1 positive  
2     2 negative  
3     3 positive
library(dplyr)
df <- data.frame(ID = c(1,1,1,1,2,2,2,2,3,3,3,3),
                 antibodies = c("positive","positive","positive","positive",
                                "negative","negative","negative","negative",
                                "negative","positive","positive","negative"),
                 AA = c(123, 345, 7567, 234, 8679, 890, 
                        812, 435345, 567, 568, 786, 678),
                 BB = c(3453, 456, 67867, 35, 78, 234235,
                        978978, 234, 786, 45645, 4756, 7567),
                 stringsAsFactors = F)

df %>% 
  group_by(ID) %>% 
  arrange(desc(antibodies)) %>% 
  summarise(antibodies = ifelse(any(antibodies == "positive"),
                                "positive",
                                "negative"),
            AA = first(AA),
            BB = first(BB))
     ID antibodies    AA    BB
  <dbl> <chr>      <dbl> <dbl>
1     1 positive     123  3453
2     2 negative    8679    78
3     3 positive     568 45645
df <- df[order(df$ID, -xtfrm(df$antibodies)),]
#df <- df[order(-xtfrm(df$antibodies)),] #Alternative if ID order not important
df[!duplicated(df$ID),]
#  ID antibodies   AA   BB
#1  1   positive  123 3453
#5  2   negative 8679   78
#9  3   positive  567  786
df <- df[order(df$antibodies),]
df[!duplicated(df$ID, fromLast = TRUE),]