подмножество строк, где значения «выключить и включить»

#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. Спасибо! Это именно то, что я искал.