Дополните и заполните недостающие строки группами неравномерной длины

У меня есть дата-фрейм руководителей округа и год их инаугурации. Я провожу панельное исследование, в котором единицей анализа является год округа. Диапазон дат — с 2000 по 2004 год.

Я хотел бы расширить df так, чтобы в нем было указано, кто был главой округа в течение каждого года с 2000 по 2004 год, но некоторые округа были созданы в середине периода моего анализа.

Моя отправная точка такова:

df <- data.frame(year= c(2000, 2001, 2003, 2000, 2002, 2004, 2003),
                  executive.name= c("Johnson", "Smith", "Alleghany", "Roberts", "Clarke", "Tollson", "Roland"),
                 party= c("PartyRed", "PartyYellow", "PartyGreen", "PartyYellow", "PartyOrange", "PartyRed", "PartyPurple"),
                  district= c(1001, 1001, 1001, 1002, 1002, 1002, 1003))

  year executive.name       party district
1 2000        Johnson    PartyRed     1001
2 2001          Smith PartyYellow     1001
3 2003      Alleghany  PartyGreen     1001
4 2000        Roberts PartyYellow     1002
5 2002         Clarke PartyOrange     1002
6 2004        Tollson    PartyRed     1002
7 2003         Roland PartyPurple     1003

Поэтому я хочу, чтобы мой df включал только годы существования района, как показано ниже:

df.neat <- data.frame(year= c(2000, 2001, 2002, 2003, 2004, 2000, 2001, 2002, 2003, 2004, 2003, 2004),
                  executive.name= c("Johnson", "Smith", "Smith", "Alleghany", "Alleghany", "Roberts", "Roberts", "Clarke", "Clarke", "Tollson", "Roland", "Roland"),
                  party= c("PartyRed", "PartyYellow", "PartyYellow", "PartyGreen", "PartyGreen", "PartyYellow", "PartyYellow", "PartyOrange", "PartyOrange", "PartyRed", "PartyPurple", "PartyPurple"),
                  district= c(1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1003, 1003))

> df.neat
   year executive.name       party district
1  2000        Johnson    PartyRed     1001
2  2001          Smith PartyYellow     1001
3  2002          Smith PartyYellow     1001
4  2003      Alleghany  PartyGreen     1001
5  2004      Alleghany  PartyGreen     1001
6  2000        Roberts PartyYellow     1002
7  2001        Roberts PartyYellow     1002
8  2002         Clarke PartyOrange     1002
9  2003         Clarke PartyOrange     1002
10 2004        Tollson    PartyRed     1002
11 2003         Roland PartyPurple     1003
12 2004         Roland PartyPurple     1003

Обратите внимание, как в 2003 году был создан округ 1003. Если я запущу команду complete, она предполагает, что 2000, 2001 и 2002 являются неявными NA. А затем fill перетаскивает последний результат из округа 1002, чтобы заполнить эти новые строки.

Другими словами, мой df выглядит так:

df |>
  tidyr::complete(district, year) |>
  tidyr::fill(executive.name, party)

# A tibble: 15 × 4
   district  year executive.name party      
      <dbl> <dbl> <chr>          <chr>      
 1     1001  2000 Johnson        PartyRed   
 2     1001  2001 Smith          PartyYellow
 3     1001  2002 Smith          PartyYellow
 4     1001  2003 Alleghany      PartyGreen 
 5     1001  2004 Alleghany      PartyGreen 
 6     1002  2000 Roberts        PartyYellow
 7     1002  2001 Roberts        PartyYellow
 8     1002  2002 Clarke         PartyOrange
 9     1002  2003 Clarke         PartyOrange
10     1002  2004 Tollson        PartyRed   
11     1003  2000 Tollson        PartyRed   
12     1003  2001 Tollson        PartyRed   
13     1003  2002 Tollson        PartyRed   
14     1003  2003 Roland         PartyPurple
15     1003  2004 Roland         PartyPurple
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
75
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Используя group_by(), это будет работать:

library(dplyr)
library(tidyr)

df <- data.frame(year= c(2000, 2001, 2003, 2000, 2002, 2004, 2003),
                 executive.name= c("Johnson", "Smith", "Alleghany", "Roberts", "Clarke", "Tollson", "Roland"),
                 party= c("PartyRed", "PartyYellow", "PartyGreen", "PartyYellow", "PartyOrange", "PartyRed", "PartyPurple"),
                 district= c(1001, 1001, 1001, 1002, 1002, 1002, 1003))

df.neat <- df |>
  complete(district, year) |>
  group_by(district) |>
  fill(executive.name, party) |>
  ungroup() |>
  arrange(district, year) |>
  filter(!is.na(executive.name)) |>
  relocate(district, .after = last_col())

df.neat
# # A tibble: 12 × 4
#     year executive.name party       district
#    <dbl> <chr>          <chr>          <dbl>
#  1  2000 Johnson        PartyRed        1001
#  2  2001 Smith          PartyYellow     1001
#  3  2002 Smith          PartyYellow     1001
#  4  2003 Alleghany      PartyGreen      1001
#  5  2004 Alleghany      PartyGreen      1001
#  6  2000 Roberts        PartyYellow     1002
#  7  2001 Roberts        PartyYellow     1002
#  8  2002 Clarke         PartyOrange     1002
#  9  2003 Clarke         PartyOrange     1002
# 10  2004 Tollson        PartyRed        1002
# 11  2003 Roland         PartyPurple     1003
# 12  2004 Roland         PartyPurple     1003

Вы могли бы filter() следующим образом, прежде чем fill()

  filter(row_number()>=min(which(!is.na(party))),.by = district) |>

Выход:

# A tibble: 12 × 4
   district  year executive.name party      
      <dbl> <dbl> <chr>          <chr>      
 1     1001  2000 Johnson        PartyRed   
 2     1001  2001 Smith          PartyYellow
 3     1001  2002 Smith          PartyYellow
 4     1001  2003 Alleghany      PartyGreen 
 5     1001  2004 Alleghany      PartyGreen 
 6     1002  2000 Roberts        PartyYellow
 7     1002  2001 Roberts        PartyYellow
 8     1002  2002 Clarke         PartyOrange
 9     1002  2003 Clarke         PartyOrange
10     1002  2004 Tollson        PartyRed   
11     1003  2003 Roland         PartyPurple
12     1003  2004 Roland         PartyPurple

Объяснение:

После complete() у вас >=0 новых строк для каждого района, а все новые строки относятся к NA для party. Вы хотите сохранить только существующие строки и новые строки, у которых номер индекса строки превышает индекс строки, где party сначала не NA

df |>
  tidyr::complete(district, year) |>
  dplyr::filter(row_number()>=min(which(!is.na(party))),.by = district) |>
  tidyr::fill(executive.name, party)

Не могли бы вы опубликовать свой полный код? Меня здесь немного смущает filter().

M-- Save the Data Dump 17.07.2024 06:21

См. обновление с полным решением.

langtang 17.07.2024 11:52
Ответ принят как подходящий

Мы можем использовать statar::fill_gap():

library(dplyr)

df %>% 
  group_by(district) %>% 
  statar::fill_gap(year, full = TRUE) %>% 
  tidyr::fill(executive.name:party, .direction = "down") %>% 
  na.omit() %>% 
  ungroup()

#> # A tibble: 12 × 4
#>     year executive.name party       district
#>    <dbl> <chr>          <chr>          <dbl>
#>  1  2000 Johnson        PartyRed        1001
#>  2  2001 Smith          PartyYellow     1001
#>  3  2002 Smith          PartyYellow     1001
#>  4  2003 Alleghany      PartyGreen      1001
#>  5  2004 Alleghany      PartyGreen      1001
#>  6  2000 Roberts        PartyYellow     1002
#>  7  2001 Roberts        PartyYellow     1002
#>  8  2002 Clarke         PartyOrange     1002
#>  9  2003 Clarke         PartyOrange     1002
#> 10  2004 Tollson        PartyRed        1002
#> 11  2003 Roland         PartyPurple     1003
#> 12  2004 Roland         PartyPurple     1003

Created on 2024-07-17 with reprex v2.0.2

Другие вопросы по теме