#r #filter #subset #tidyverse
#r #Фильтр #подмножество #tidyverse
Вопрос:
У меня есть набор данных о политических ответах стран на коронавирус, и я отображаю ответы каждой страны в виде меток с помощью geom_text. Я создал пример набора данных о том, как могут выглядеть значения одной политики для одной страны. Если значение политики равно 0, то активной политики нет. Политика активна, если она находится в диапазоне от 1 до 5, и масштаб политики увеличивается по мере ее увеличения.
Итак, проблема, с которой я столкнулся, заключалась в том, что я хотел подмножить все даты начала и окончания политик, чтобы позже я мог отобразить их в виде меток. Мне удалось выполнить это, используя столбец с запаздывающими значениями и столбец с опережающими значениями. Используя их, я смог определить, когда политика «включена», проверив, было ли предыдущее значение каким-либо значением, отличным от значения политики. Я сделал то же самое для конца политики, но на этот раз с ведущим значением.
Мой вопрос просто в том, что я хотел узнать, знает ли кто-нибудь о более эффективном способе сделать это, спасибо.
Редактировать: Изменены некоторые имена переменных и добавлены в выходные данные для переменных начала / конца политики меток.
library(tidyverse)
# 0 represents no policy being active
# the values 1-5 represent a growing scale of the policy
num <- c(rep(0, 5), rep(1, 5), rep(2, 4), rep(0,8), rep(3, 4), rep(0, 5), rep(2, 4), rep(0, 2))
num
#> [1] 0 0 0 0 0 1 1 1 1 1 2 2 2 2 0 0 0 0 0 0 0 0 3 3 3 3 0 0 0 0 0 2 2 2 2 0 0
# simple dates
date <- seq(as.Date("2020/09/01"), by = "day", length.out = length(num))
# making the dataframe
df <- data.frame(date, num)
#creating a lag to try to help filter out when policies started and ended
df <- df %>%
mutate(lag = lag(num), # lag for previous value
lead = lead(num)) # lead for next value
# filtering when the policies "turn on"
policy_start <- df %>%
filter(num == 1 amp; lag %in% c(0, 2, 3, 4, 5) |
num == 2 amp; lag %in% c(0, 1, 3, 4, 5) |
num == 3 amp; lag %in% c(0, 1, 2, 4, 5) |
num == 4 amp; lag %in% c(0, 1, 2, 3, 5) |
num == 5 amp; lag %in% c(0, 1, 2, 3, 4))
policy_start
#> date num lag lead
#> 1 2020-09-06 1 0 1
#> 2 2020-09-11 2 1 2
#> 3 2020-09-23 3 0 3
#> 4 2020-10-02 2 0 2
# filtering when the policies "turn off"
policy_end <- df %>%
filter(num == 1 amp; lead %in% c(0, 2, 3, 4, 5) |
num == 2 amp; lead %in% c(0, 1, 3, 4, 5) |
num == 3 amp; lead %in% c(0, 1, 2, 4, 5) |
num == 4 amp; lead %in% c(0, 1, 2, 3, 5) |
num == 5 amp; lead %in% c(0, 1, 2, 3, 4))
policy_end
#> date num lag lead
#> 1 2020-09-10 1 1 2
#> 2 2020-09-14 2 2 0
#> 3 2020-09-26 3 3 0
#> 4 2020-10-05 2 2 0
Создано 2020-09-16 пакетом reprex (версия 0.3.0)
Ответ №1:
После создания фрейма данных без запаздывающих значений и опережающих значений.
#subsetting the rows
policy <- c()
for(i in 1:length(df$num)){
policy[i] <- case_when(df$num[i]>0 amp; df$num[i]!=df$num[i-1] ~ "start",
df$num[i]>0 amp; df$num[i]!=df$num[i 1] ~ "end")
}
#Creating a dataframe with a column with "start" and "end" of policies
df <- cbind(df,policy)
df
#> date num policy
#>1 2020-09-01 0 <NA>
#>2 2020-09-02 0 <NA>
#>3 2020-09-03 0 <NA>
#>4 2020-09-04 0 <NA>
#>5 2020-09-05 0 <NA>
#>6 2020-09-06 1 start
#>7 2020-09-07 1 <NA>
#>8 2020-09-08 1 <NA>
#>9 2020-09-09 1 <NA>
#>10 2020-09-10 1 end
Комментарии:
1. Спасибо! Это именно то, что я искал.