【问题标题】:How to delete rows using conditions in R?如何使用 R 中的条件删除行?
【发布时间】:2022-01-20 19:47:29
【问题描述】:

我在 R 中有一个包含超过 800k obs 的数据集。它看起来像这样:

id <- c("58497484", "58544005", "74766653", "74764718", "62824455", "58497484", "58497484", "74766653", "58544005")
key <- c("5718368_09/06/1981_3_2014", "2077485_02/06/1977_8_2014", "2091585_23/10/1982_1_2014", "2077388_30/01/2000_11_2017", "2082225_02/07/1998_10_2017", 
         "2077450_04/05/2001_1_2016", "2077477_03/03/1978_8_2017", 
         "2077388_30/01/2020_11_2019", "5718368_08/06/1982_3_2012")
out <- c("2.1 - Reason 1", "1.2 - Reason 2", "1.2 - Reason 2", "1.2 - Reason 2", "1.2 - Reason 2", "1.3 - Reason 3" , 
         "1.2 - Reason 2", "3.6 - Reason 8", "3.2 - Reason 10")
flag1 <- c("1", "0", "1", "1", "1", "1", "0", "1", "0")
flag2 <- c("0", "0", "0", "1", "0", "1", "0", "1", "0")

data <- as.data.frame(cbind(id, key, out, flag1, flag2))

我的一些身份证号码会重复。我需要做的是对这些 ID 进行分组,这样我就可以看到所有分组的 obs。我使用此代码这样做:

data <- data %>% 
  arrange(id) %>% 
  mutate(id = ifelse(duplicated(id), "", id))

当我这样做时,我的 df 看起来像这样:

   id                 key                        out         flag1   flag2
58497484     5718368_09/06/1981_3_2014      2.1 - Reason 1    1        0
             2077450_04/05/2001_1_2016      1.3 - Reason 3    1        1
             2077477_03/03/1978_8_2017      1.2 - Reason 2    0        0

58544005     2077485_02/06/1977_8_2014      1.2 - Reason 2    0        0
             5718368_08/06/1982_3_2012      3.2 - Reason 10   0        0

62824455     2082225_02/07/1998_10_2017     1.2 - Reason 2    1        0
74764718     2077388_30/01/2000_11_2017     1.2 - Reason 2    1        1

74766653     2091585_23/10/1982_1_2014      1.2 - Reason 2    1        0
             2077388_30/01/2020_11_2019     3.6 - Reason 8    1        1

我需要做的是使用“out”、“flag1”和“flag2”变量作为条件删除集群。它是这样的:如果我的分组 id 中的任何行以“out”2 或 3 开头,并且“flag1”和“flag2”都等于零 (0)。我想要的输出如下:

id                 key                        out         flag1   flag2
58497484     5718368_09/06/1981_3_2014      2.1 - Reason 1    1        0
             2077450_04/05/2001_1_2016      1.3 - Reason 3    1        1
             2077477_03/03/1978_8_2017      1.2 - Reason 2    0        0

62824455     2082225_02/07/1998_10_2017     1.2 - Reason 2    1        0
74764718     2077388_30/01/2000_11_2017     1.2 - Reason 2    1        1

74766653     2091585_23/10/1982_1_2014      1.2 - Reason 2    1        0
             2077388_30/01/2020_11_2019     3.6 - Reason 8    1        1

请注意,输出中不存在“58544005”id 编号,因为它显示了等于 0 的标志和“out”原因 3.2。提前致谢。

【问题讨论】:

  • 看起来其他人正在处理此数据:https://stackoverflow.com/q/70325584/2799941
  • @andrew_reece 是的,我们都在同一个地方工作! :)
  • 删除的条件似乎和每个id是否有多行无关。您能否澄清一下 - 您是否只是想删除您提到的三个条件为真的任何行,或者是否有一些考虑 id 应该包括在内?
  • @kybazzi 如果分组的id出现3个条件,我想删除。 ID“58544005”具有以 3 开头且两个标志都等于 0 的“out”原因。另一方面,ID“58497484”具有以 2 开头的“out”原因,但它的行标志不等于零,只是第三行两个标志都为零,所以我想保留这个集群。跨度>

标签: r if-statement dplyr


【解决方案1】:
library(tidyverse)

data %>%
  arrange(id)%>%
  type.convert(as.is = TRUE)%>%
  group_by(id) %>%
  filter(!(if_all(flag1:flag2, ~sum(.x)==0)& 
         any(substr(out, 1, 1) %in% 2:3))) %>%
  ungroup() %>%
  mutate(id = replace(id, duplicated(id), ''))

# A tibble: 7 x 5
  id         key                        out            flag1 flag2
  <chr>      <chr>                      <chr>          <int> <int>
1 "58497484" 5718368_09/06/1981_3_2014  2.1 - Reason 1     1     0
2 ""         2077450_04/05/2001_1_2016  1.3 - Reason 3     1     1
3 ""         2077477_03/03/1978_8_2017  1.2 - Reason 2     0     0
4 "62824455" 2082225_02/07/1998_10_2017 1.2 - Reason 2     1     0
5 "74764718" 2077388_30/01/2000_11_2017 1.2 - Reason 2     1     1
6 "74766653" 2091585_23/10/1982_1_2014  1.2 - Reason 2     1     0
7 ""         2077388_30/01/2020_11_2019 3.6 - Reason 8     1     1

【讨论】:

    【解决方案2】:

    根据您在 cmets 中的说明,您似乎想要删除 id 的所有记录,其中该 id 的 any 记录满足三个条件。这是我将使用的策略:

    1. 对于每一行,检查是否满足删除条件。

    2. 对于每个 id,检查是否有任何记录被设置为删除。如果是这样,请删除 id。

    library(tidyverse)
    data %>% 
      # Step 1: Create an indicator for deletion for each record
      mutate(
        delete_ind = 
          str_sub(out, 1, 1) %in% c("2", "3") & 
          flag1 == 0 &
          flag2 == 0
      ) %>% 
      # Step 2: Filter out all id's that satisfied the condition at least once
      group_by(id) %>% 
      filter(sum(delete_ind) == 0) %>% 
      ungroup()
    
    # A tibble: 7 x 6
      id       key                        out            flag1 flag2 delete_ind
      <chr>    <chr>                      <chr>          <chr> <chr> <lgl>     
    1 58497484 5718368_09/06/1981_3_2014  2.1 - Reason 1 1     0     FALSE     
    2 74766653 2091585_23/10/1982_1_2014  1.2 - Reason 2 1     0     FALSE     
    3 74764718 2077388_30/01/2000_11_2017 1.2 - Reason 2 1     1     FALSE     
    4 62824455 2082225_02/07/1998_10_2017 1.2 - Reason 2 1     0     FALSE     
    5 58497484 2077450_04/05/2001_1_2016  1.3 - Reason 3 1     1     FALSE     
    6 58497484 2077477_03/03/1978_8_2017  1.2 - Reason 2 0     0     FALSE     
    7 74766653 2077388_30/01/2020_11_2019 3.6 - Reason 8 1     1     FALSE 
    

    【讨论】:

    • 我错过了您关于按 id 排列并将 id 设置为 "" 重复案例的问题部分 - 但您似乎已经有了解决该部分的方法。
    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 2022-08-09
    • 2023-01-18
    • 2019-06-05
    • 2020-09-03
    • 2018-08-06
    • 2015-08-31
    • 2021-06-09
    相关资源
    最近更新 更多