【问题标题】:How to filter using conditions in R?如何使用 R 中的条件进行过滤?
【发布时间】:2022-01-16 09:21:26
【问题描述】:

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

id <- c("58497484", "58544005", "74766653", "74764718", "62824455", "58497484", "58497484", "74766653")
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")
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")

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

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

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

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

     id                  key                         out
    58497484     5718368_09/06/1981_3_2014      2.1 - Reason 1
                 2077450_04/05/2001_1_2016      1.3 - Reason 3
                 2077477_03/03/1978_8_2017      1.2 - Reason 2
    
    58544005     2077485_02/06/1977_8_2014      1.2 - Reason 2
    62824455     2082225_02/07/1998_10_2017     1.2 - Reason 2
    74764718     2077388_30/01/2000_11_2017     1.2 - Reason 2

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

我现在需要做的是使用变量“out”过滤我的 df,但是如果“out”以 2 或 3 开头,我想将所有寄存器分组,所以我的 df 看起来像这样:

  id                  key                         out
58497484     5718368_09/06/1981_3_2014      2.1 - Reason 1
             2077450_04/05/2001_1_2016      1.3 - Reason 3
             2077477_03/03/1978_8_2017      1.2 - Reason 2       
74766653     2091585_23/10/1982_1_2014      1.2 - Reason 2
             2077388_30/01/2020_11_2019     3.6 - Reason 8 

有什么办法可以做到吗?提前致谢。

【问题讨论】:

  • 如果out 中的任何 个值以2 或3 开头,而不是全部开头,您似乎想要保留id。对吗?
  • @andrew_reece 完全正确!
  • 如果有重复,你真的需要删除id吗?或者您是否只需要按 R 对常见的 id 值进行逻辑分组?实际上,将重复的 id 值更改为空字符串似乎比实际更美观。
  • @andrew_reece 我需要将其更改为空字符串,因为它更容易识别哪个 obs 属于该 id,因为我要将这个 df 呈现给我的老板,它更容易理解。但你是对的,它完全是化妆品! :)
  • @TarJae 我的意思是,如果任何“out”变量行字符串以 2 或 3 开头,我想保持所有行的 ID 相同。

标签: r if-statement dplyr


【解决方案1】:

最初,不是将duplicated 'id' 更改为空白 (''),而是先按filter 进行分组,然后对'id' 进行更改

library(dplyr)
library(stringr)
data %>% 
   group_by(id) %>% 
   dplyr::filter(any(str_detect(out, "^(2|3)"))) %>% 
   ungroup %>%
   arrange(id) %>%
   mutate(id = replace(id, duplicated(id), ""))

-输出

# A tibble: 5 × 3
  id         key                        out           
  <chr>      <chr>                      <chr>         
1 "58497484" 5718368_09/06/1981_3_2014  2.1 - Reason 1
2 ""         2077450_04/05/2001_1_2016  1.3 - Reason 3
3 ""         2077477_03/03/1978_8_2017  1.2 - Reason 2
4 "74766653" 2091585_23/10/1982_1_2014  1.2 - Reason 2
5 ""         2077388_30/01/2020_11_2019 3.6 - Reason 8

【讨论】:

  • 我看到我的答案与你的基本相同 - 我很高兴删除但我也很好奇 OP 是否真的需要将 id 转为空字符串,如果是这样,那么考虑删除 replace行...
  • @akrun 这工作得很好!非常感谢。
  • @LanaMeijinhos 谢谢
  • @andrew_reece 对不起,我没有看到你的答案。离开了。
  • @LanaMeijinhos 正如 andrew_reece 提到的,可能不需要将重复的元素替换为空白
【解决方案2】:

虽然 akrun 是最好的方法,但我想提供另一种创建帮助列的方法:

  data %>% 
    group_by(id) %>% 
    summarise(key, out) %>% 
    mutate(x = as.integer(substr(out, 1,1))) %>% 
    filter(any(x %in% 2 | x %in% 3)) %>%     
    mutate(id = ifelse(duplicated(id), "", id)) %>% 
    select(-x)
  id         key                        out           
  <chr>      <chr>                      <chr>         
1 "58497484" 5718368_09/06/1981_3_2014  2.1 - Reason 1
2 ""         2077450_04/05/2001_1_2016  1.3 - Reason 3
3 ""         2077477_03/03/1978_8_2017  1.2 - Reason 2
4 "74766653" 2091585_23/10/1982_1_2014  1.2 - Reason 2
5 ""         2077388_30/01/2020_11_2019 3.6 - Reason 8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多