Создайте переменную со значением один после обработки в году X и 0 в противном случае.

У меня есть панельные данные бразильских муниципалитетов за 1995-2013 годы. Код - это идентификатор муниципалитета. Ном - это название муниципалитета, а ano - год принятия государственной политики (ноль означает, что они никогда не применяли политику).

     code                 Nome  ano
1 1100015 ALTA FLORESTA DOESTE 2010
2 1100023            ARIQUEMES 2006
3 1100031               CABIXI    0
4 1100049               CACOAL 2006
5 1100056           CEREJEIRAS 2014
6 1100064    COLORADO DO OESTE 2006

У меня такой вопрос:

Как мне сгенерировать фиктивную переменную в R со значением 1 после принятия государственной политики муниципалитетом X в году Z и 0 в противном случае?

Ниже вы можете увидеть ожидаемый результат в широком формате, который легче визуализировать. (Однако я преобразую данные в длинный формат, чтобы объединить их с другими данными. Как видите, данные в этом примере начинаются только после 2006 г. или никогда.)

      code                      Nome 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
1  1100015      ALTA FLORESTA DOESTE    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    1    1    1    1
2  1100023                 ARIQUEMES    0    0    0    0    0    0    0    0    0    0    0    1    1    1    1    1    1    1    1
3  1100031                    CABIXI    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
4  1100049                    CACOAL    0    0    0    0    0    0    0    0    0    0    0    1    1    1    1    1    1    1    1
5  1100056                CEREJEIRAS    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
6  1100064         COLORADO DO OESTE    0    0    0    0    0    0    0    0    0    0    0    1    1    1    1    1    1    1    1

Я нашел похожие вопросы на этом форуме, но не тот, который задаю.


person user1290547    schedule 13.10.2019    source источник
comment
Спасибо! Редактировал вопрос.   -  person user1290547    schedule 14.10.2019


Ответы (1)


Вот вариант с использованием tidyverse. Создайте list столбец с последовательностью от каждого значения «ano» до 2013, unnest столбец list, создайте столбец с единицами («val»), сгруппированный по «code», «Nome», разверните набор данных с помощью complete для последовательности из С 1995 по 2013 год, fill обозначив "val" значением 0 там, где комбинация отсутствует, ungroup и измените его форму на "широкий" формат с помощью pivot_wider

library(dplyr)
library(tidyr) #1.0.0
library(purrr)
df1 %>%
   mutate(ano = case_when(between(ano, 1995, 2013) ~ 
        map(ano, ~ .x:2013), TRUE ~ list(NA_integer_))) %>% 
   unnest(ano) %>% 
   mutate(val = 1) %>%
   group_by(code, Nome) %>% 
   complete(ano = 1995:2013, fill = list(val = 0)) %>%
   ungroup %>% 
   filter(!is.na(ano)) %>%
   pivot_wider(names_from = ano, values_from = val)
# A tibble: 6 x 21
#     code Nome                 `1995` `1996` `1997` `1998` `1999` `2000` `2001` `2002` `2003` `2004` `2005` `2006` `2007` `2008` `2009` `2010` `2011` `2012` `2013`
#    <int> <chr>                 <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#1 1100015 ALTA FLORESTA DOESTE      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      1      1      1      1
#2 1100023 ARIQUEMES                 0      0      0      0      0      0      0      0      0      0      0      1      1      1      1      1      1      1      1
#3 1100031 CABIXI                    0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0
#4 1100049 CACOAL                    0      0      0      0      0      0      0      0      0      0      0      1      1      1      1      1      1      1      1
#5 1100056 CEREJEIRAS                0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0      0
#6 1100064 COLORADO DO OESTE         0      0      0      0      0      0      0      0      0      0      0      1      1      1      1      1      1      1      1

данные

df1 <- structure(list(code = c(1100015L, 1100023L, 1100031L, 1100049L, 
1100056L, 1100064L), Nome = c("ALTA FLORESTA DOESTE", "ARIQUEMES", 
"CABIXI", "CACOAL", "CEREJEIRAS", "COLORADO DO OESTE"), ano = c(2010L, 
2006L, 0L, 2006L, 2014L, 2006L)), class = "data.frame", row.names = c(NA, 
-6L))
person akrun    schedule 14.10.2019
comment
Большое вам спасибо за ваш ответ. Когда я использую реальные данные, я получаю следующее сообщение: Ошибка: несовместимо с запрошенным типом: [type = character; target = double]. Вы знаете, почему это происходит? - person user1290547; 15.10.2019
comment
@ user1290547 Можете ли вы сравнить str(yourdata) с str(df1), возможно, "ano" в вашем исходном наборе данных не является числовым. - person akrun; 15.10.2019
comment
Еще раз спасибо! Вы мне очень помогли! Я проверил str (mydata), и вы были правы - ano было символом. Затем я изменил способ кодирования данных, и код заработал. Я все еще получаю следующее сообщение: Предупреждение: between () вызывается для числового вектора с классом S3. Не знаю, важно ли это. Извините, я относительно новичок в R. - person user1290547; 16.10.2019
comment
@ user1290547 Если это предупреждение, и оно все еще работает, это не так уж и проблематично, поскольку это может быть дружественное предупреждение - person akrun; 16.10.2019