r - 在一行中搜索 r 中的一系列值
问题描述
解释这是一项复杂的任务,但我试图逐行查看几列,以搜索 3 次或更多连续出现的模式FALSE
,但前提是这之前至少有一个TRUE
.
在找到这种模式的地方,我想添加一个新列date_lost
,显示发生这种情况的日期(日期取自列标题 - 我知道这不是命名列的最佳方式,但这就是数据框的方式被建立)
一个简单的数据框可能如下所示:
library(tidyverse)
df <-
tribble(
~id, ~`01/01/18`, ~`02/01/18`, ~`03/01/18`, ~`04/01/18`, ~`05/01/18`,
1, NA, NA, TRUE, TRUE, FALSE,
2, TRUE, TRUE, FALSE, FALSE, FALSE,
3, TRUE, FALSE, FALSE, FALSE, TRUE,
4, FALSE, TRUE, FALSE, TRUE, FALSE,
5, TRUE, FALSE, FALSE, TRUE, TRUE,
6, FALSE, FALSE, FALSE, TRUE, FALSE,
7, NA, NA, NA, NA, NA
)
> df
# A tibble: 7 x 6
id `01/01/18` `02/01/18` `03/01/18` `04/01/18` `05/01/18`
<dbl> <lgl> <lgl> <lgl> <lgl> <lgl>
1 1 NA NA TRUE TRUE FALSE
2 2 TRUE TRUE FALSE FALSE FALSE
3 3 TRUE FALSE FALSE FALSE TRUE
4 4 FALSE TRUE FALSE TRUE FALSE
5 5 TRUE FALSE FALSE TRUE TRUE
6 6 FALSE FALSE FALSE TRUE FALSE
7 7 NA NA NA NA NA
该函数将识别在第 2 行和第 3 行中找到此模式,并在新列date_lost
中添加日期(05/01/18
第 204/01/18
行和第 3 行)。NA
如果未找到此模式,则其他行可能有,如下所示:
# A tibble: 7 x 7
id `01/01/18` `02/01/18` `03/01/18` `04/01/18` `05/01/18` date_lost
<dbl> <lgl> <lgl> <lgl> <lgl> <lgl> <chr>
1 1 NA NA TRUE TRUE FALSE NA
2 2 TRUE TRUE FALSE FALSE FALSE 05/01/18
3 3 TRUE FALSE FALSE FALSE TRUE 04/01/18
4 4 FALSE TRUE FALSE TRUE FALSE NA
5 5 TRUE FALSE FALSE TRUE TRUE NA
6 6 FALSE FALSE FALSE TRUE FALSE NA
7 7 NA NA NA NA NA NA
我确信这可以在 中以一种优雅的方式完成r
,但我只是无法找到这样的方式。非常感谢您的帮助
解决方案
这是一个解决方案,它使用了一些重塑(使用列而不是行)和一些分组,以便发现(3+)连续的 FALSE 案例,其中(1+) TRUE 在它们之前。
library(tidyverse)
library(data.table)
df <-
tribble(
~id, ~`01/01/18`, ~`02/01/18`, ~`03/01/18`, ~`04/01/18`, ~`05/01/18`,
1, NA, NA, TRUE, TRUE, FALSE,
2, TRUE, TRUE, FALSE, FALSE, FALSE,
3, TRUE, FALSE, FALSE, FALSE, TRUE,
4, FALSE, TRUE, FALSE, TRUE, FALSE,
5, TRUE, FALSE, FALSE, TRUE, TRUE,
6, FALSE, FALSE, FALSE, TRUE, FALSE,
7, NA, NA, NA, NA, NA
)
df %>%
gather(date, value, -id) %>% # reshape data
arrange(id) %>% # arrange data by id
group_by(id2 = rleid(id, value)) %>% # create a new grouping (to spot consequtive FALSE cases)
mutate(value = ifelse(is.na(as.character(value)),
".",
as.character(value)), # update value variable (NAs will break the grouping, so we replace them with ".")
false_in_row = sum(value == "FALSE")) %>% # count how many FALSE in a row
group_by(id) %>% # group by id column
mutate(flag = cumsum(value == "TRUE")) %>% # create a flag to spot if you had TRUE before FALSE cases
filter(flag >= 1 & false_in_row >= 3) %>% # keep only conditions you specified
summarise(date_lost = nth(date, 3)) %>% # get date the matches your conditions
right_join(df, by="id") # join original dataset
# # A tibble: 7 x 7
# id date_lost `01/01/18` `02/01/18` `03/01/18` `04/01/18` `05/01/18`
# <dbl> <chr> <lgl> <lgl> <lgl> <lgl> <lgl>
# 1 1 NA NA NA TRUE TRUE FALSE
# 2 2 05/01/18 TRUE TRUE FALSE FALSE FALSE
# 3 3 04/01/18 TRUE FALSE FALSE FALSE TRUE
# 4 4 NA FALSE TRUE FALSE TRUE FALSE
# 5 5 NA TRUE FALSE FALSE TRUE TRUE
# 6 6 NA FALSE FALSE FALSE TRUE FALSE
# 7 7 NA NA NA NA NA NA
推荐阅读
- python - Django中的`assertIn`和`assertContains`有什么区别?
- python - 如何根据数据框中各个列的不同布尔标准创建新列
- c++ - “向量”的存储大小未知
- java - 如何为我的扫描仪文件阅读器修复 java.util.InputMismatchException?
- excel - 当 Excel VBA 从关闭的工作簿中读取数据而不打开它时,它到底在做什么?
- python - 树莓派键盘分配器
- javascript - 如果日期值小于当前日期,如何更改水平条的背景颜色?
- sql-server - SQL Server 存储过程中的 NUMERIC(18, @variable)
- php - 有没有办法像这样在 MySQL 中显示一个数组?(“一”=>“1”)
- php - wordpress 阅读更多不起作用,它显示完整内容