【问题标题】:Selecting rows conditioned on other columns of data frame in r在r中选择以其他数据框列为条件的行
【发布时间】:2021-01-21 22:53:04
【问题描述】:

我有一个这样的数据集

id <- rep(c("A", "B", "C", "D", "E"), 5)

year <- rep( c(2001 : 2005), each = 5)

status <- c(0, 0, 2, 0, 4, 0, 0, 3, 0, 1, 0, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4 ) 

dt <- data.frame( year, id, status)

注意 2003 年的野兔 ID BD Status &gt; 0 其他年份不是。我的目标是找到 2003 年的 Id 在所有其他年份的状态 > 1 和状态 = 0 的观察结果。如果一个 Id 没有全年的观察结果,我不会认为即使在此数据中所有 Id 全年都存在。

我做的是一个漫长的过程,而且没有效果-

id1 <- dt %>% filter(year == 2003 & status > 1)
id1 <- id1[["id"]]

dt1 <-   dt[dt$id %in% id1, ]


dt2 <- dt1 %>% filter(year != 2003) 

dt2<- dt2 %>% mutate( st2 = case_when( status == 1 ~ 0, TRUE ~ status)  )


dt2<- setDT(dt2)[, fact := +(uniqueN(st2) == 1), id]

dt2 <- dt2 %>% filter(fact == 1 ) %>% filter(st2 == 0)

id2 <- dt2[["id"]]

dt <- dt1[dt1$id %in% id2, ]

rm(id1, id2, dt1, dt2)

我认为这给了我想要的输出,但对重复性工作无效。非常感谢您帮助我找到更好的解决方法。

注意:我是 r 和编程方面的新手 - 对没有组织的问题表示歉意。

感谢您的帮助!!!!

【问题讨论】:

  • 您好,您能否在发布问题时确保您的代码和数据同步且完全可重现?例如,您的数据框中有Year,但在代码中使用yearStatus 也一样。

标签: r dplyr data-manipulation


【解决方案1】:

如果我们要选择满足条件的Ids

library(dplyr)
dt %>%
   group_by(Id) %>%
   filter(Status[Year == 2003]  > 1 & all(Status[Year != 2003] == 0))

【讨论】:

  • 无法弄清楚为什么我得到这个 - 错误:结果的长度必须为 10,而不是 2。我运行的代码是 ``` data_05 % group_by(frs_id) % >% 过滤器(v_status[year == 2005]>1 & all(v_status[year != 2005]
  • @AhadZaman 是否有可能某些 'Id' 没有 Year 作为 2003 年
  • 是的,有些“Id”没有年份为 2003 @akrun
  • @AhadZaman 这可能是原因。如果某些 ID 没有这些,那么该 ID 的预期值应该是什么
【解决方案2】:

data.table 选项

setDT(dt)[, Status[Year == 2003] > 0 & sum(Status > 0) == 1, Id]

给予

   Id    V1
1:  A FALSE
2:  B  TRUE
3:  C FALSE
4:  D  TRUE
5:  E FALSE

如果要过滤掉想要的Ids,可以运行

> setDT(dt)[, .SD[Status[Year == 2003] > 0 & sum(Status > 0) == 1], Id]
    Id Year Status
 1:  B 2001      0
 2:  B 2002      0
 3:  B 2003      4
 4:  B 2004      0
 5:  B 2005      0
 6:  D 2001      0
 7:  D 2002      0
 8:  D 2003      2
 9:  D 2004      0
10:  D 2005      0

【讨论】:

  • 感谢您的帮助。我很难理解代码中的 `sum(Status > 0) == 1`。我在哪里可以获得一些关于构建这种条件语句的材料?谢谢@ThomaslsCoding
【解决方案3】:

如果你只是想过滤,你可以这样做:

library(dplyr)

dplyr::filter(dt, (Year == 2003 & Status > 0) | (Year != 2003 & Status == 0))

 Year Id Status
1  2001  A      0
2  2001  B      0
3  2001  D      0
4  2002  A      0
5  2002  B      0
6  2002  D      0
7  2003  B      4
8  2003  C      2
9  2003  D      2
10 2003  E      1
11 2004  A      0
12 2004  B      0
13 2004  C      0
14 2004  D      0
15 2004  E      0
16 2005  A      0
17 2005  B      0
18 2005  D      0

如果您想要满足条件的独特Id,那么您只需将管道添加到dplyr::distinct

dplyr::filter(dt, (Year == 2003 & Status > 0) | (Year != 2003 & Status == 0)) %>% 
  dplyr::distinct(Id)

  Id
1  A
2  B
3  D
4  C
5  E

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-15
    • 1970-01-01
    相关资源
    最近更新 更多