У меня есть дата-фрейм руководителей округа и год их инаугурации. Я провожу панельное исследование, в котором единицей анализа является год округа. Диапазон дат — с 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
Используя 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)
См. обновление с полным решением.
Мы можем использовать 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
Не могли бы вы опубликовать свой полный код? Меня здесь немного смущает
filter()
.