我可以按列创建一个包含一系列值的标志列吗?
Can I create a flag column with a sequence of values by columns?
很难解释,但我有一个 data.frame(2.915 行),其中包含 ID 列和年份列:
在此 data.frame 中,我想验证是否有任何 ID 在列中具有序列 1,0(一年或多年零),1*。
像这样:
我的意思是,标志栏会很有用。
data$flag[data$ID %in% seq] <- c("Y")
我该怎么做?
我的数据:
structure(list(ID = c("5453", "6675", "7745",
"68621", "33356", "7855"), `2000` = c(0,
0, 1, 0, 1, 0), `2001` = c(0, 0, 1, 0, 1, 0), `2002` = c(0, 0,
1, 0, 1, 0), `2003` = c(0, 0, 1, 0, 1, 0), `2004` = c(1, 0, 1,
0, 1, 1), `2005` = c(0, 1, 1, 0, 1, 1), `2006` = c(1, 1, 1, 0,
1, 1), `2007` = c(1, 1, 1, 0, 1, 1), `2008` = c(1, 1, 1, 1, 1,
1), `2009` = c(1, 1, 1, 1, 1, 1), `2010` = c(1, 1, 1, 1, 0, 1
), `2011` = c(1, 1, 1, 0, 0, 1), `2012` = c(1, 1, 1, 0, 0, 1),
`2013` = c(1, 1, 1, 0, 0, 1), `2014` = c(1, 1, 1, 0, 0, 1
), `2015` = c(1, 1, 1, 0, 0, 1), `2016` = c(1, 1, 1, 0, 0,
1), `2017` = c(0, 0, 0, 0, 0, 0), `2018` = c(0, 0, 0, 0,
0, 0)), row.names = c(NA, 6L), class = "data.frame")
根据您给定的数据 df
:
library(dplyr)
library(tidyr)
flag_valley <- function(x) {
num_changes <- sum(abs(diff(x)))
first_val <- x[1]
return(num_changes >= 3 | num_changes >= 2 & first_val == 1)
}
df %>%
pivot_longer(matches("^\d{4}$"), names_to = "year", values_to = "val") %>%
group_by(ID) %>%
summarize(flag = flag_valley(val))
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 6 x 2
#> ID flag
#> <chr> <lgl>
#> 1 33356 FALSE
#> 2 5453 TRUE
#> 3 6675 FALSE
#> 4 68621 FALSE
#> 5 7745 FALSE
#> 6 7855 FALSE
flag_valley
函数查看序列是否改变了 3 次或更多次(在这种情况下必须有 '1(0+)1' 模式)或者序列是否从 1 开始并改变2 次或更多次(在这种情况下,模式也必须出现)。
请注意,这仅在可能的值为 0 和 1 时有效。
我们可以使用lead
得到下一个值
library(dplyr)
df %>%
tidyr::pivot_longer(cols = -ID) %>%
group_by(ID) %>%
summarise(flag = any(value == 1 & lead(value) == 0 & lead(value, 2) == 1))
# A tibble: 6 x 2
# ID flag
# <chr> <lgl>
#1 33356 FALSE
#2 5453 TRUE
#3 6675 FALSE
#4 68621 FALSE
#5 7745 FALSE
#6 7855 FALSE
很难解释,但我有一个 data.frame(2.915 行),其中包含 ID 列和年份列:
在此 data.frame 中,我想验证是否有任何 ID 在列中具有序列 1,0(一年或多年零),1*。
像这样:
我的意思是,标志栏会很有用。
data$flag[data$ID %in% seq] <- c("Y")
我该怎么做?
我的数据:
structure(list(ID = c("5453", "6675", "7745",
"68621", "33356", "7855"), `2000` = c(0,
0, 1, 0, 1, 0), `2001` = c(0, 0, 1, 0, 1, 0), `2002` = c(0, 0,
1, 0, 1, 0), `2003` = c(0, 0, 1, 0, 1, 0), `2004` = c(1, 0, 1,
0, 1, 1), `2005` = c(0, 1, 1, 0, 1, 1), `2006` = c(1, 1, 1, 0,
1, 1), `2007` = c(1, 1, 1, 0, 1, 1), `2008` = c(1, 1, 1, 1, 1,
1), `2009` = c(1, 1, 1, 1, 1, 1), `2010` = c(1, 1, 1, 1, 0, 1
), `2011` = c(1, 1, 1, 0, 0, 1), `2012` = c(1, 1, 1, 0, 0, 1),
`2013` = c(1, 1, 1, 0, 0, 1), `2014` = c(1, 1, 1, 0, 0, 1
), `2015` = c(1, 1, 1, 0, 0, 1), `2016` = c(1, 1, 1, 0, 0,
1), `2017` = c(0, 0, 0, 0, 0, 0), `2018` = c(0, 0, 0, 0,
0, 0)), row.names = c(NA, 6L), class = "data.frame")
根据您给定的数据 df
:
library(dplyr)
library(tidyr)
flag_valley <- function(x) {
num_changes <- sum(abs(diff(x)))
first_val <- x[1]
return(num_changes >= 3 | num_changes >= 2 & first_val == 1)
}
df %>%
pivot_longer(matches("^\d{4}$"), names_to = "year", values_to = "val") %>%
group_by(ID) %>%
summarize(flag = flag_valley(val))
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 6 x 2
#> ID flag
#> <chr> <lgl>
#> 1 33356 FALSE
#> 2 5453 TRUE
#> 3 6675 FALSE
#> 4 68621 FALSE
#> 5 7745 FALSE
#> 6 7855 FALSE
flag_valley
函数查看序列是否改变了 3 次或更多次(在这种情况下必须有 '1(0+)1' 模式)或者序列是否从 1 开始并改变2 次或更多次(在这种情况下,模式也必须出现)。
请注意,这仅在可能的值为 0 和 1 时有效。
我们可以使用lead
得到下一个值
library(dplyr)
df %>%
tidyr::pivot_longer(cols = -ID) %>%
group_by(ID) %>%
summarise(flag = any(value == 1 & lead(value) == 0 & lead(value, 2) == 1))
# A tibble: 6 x 2
# ID flag
# <chr> <lgl>
#1 33356 FALSE
#2 5453 TRUE
#3 6675 FALSE
#4 68621 FALSE
#5 7745 FALSE
#6 7855 FALSE