![](/img/trans.png)
[英]R statistics, panel data and NAs: replacing NA value in vector with a specific row in another vector using panel data
[英]Replacing NAs with prior year value for specific country in panel data
我已經合並了兩個數據框,分別稱為 A 和 B。其中一個具有每年重要變量的值以及一些缺失的數據,我將分別處理這些數據。 第二個只有特定年份(選舉年)的值。 這是跨國家面板數據,具有國家年觀察單位,因此在任何操作中區分國家和年份非常重要。 合並后,非選舉年的數據如預期的那樣具有來自第二個 dataframe 的數據的 NA 值。 這些 NA 需要填寫該特定國家上一次選舉的數據,直到該國家的下一次選舉。 我不想為來自 dataframe A 的數據填寫任何 NA。
(對於可能有理論問題的人來說,B的數據是關於執政黨的,所以理論上這樣填寫數據是合理的。)
如果我按國家/地區對數據進行子集化,我可以使用 tidy::fill function 輕松完成此操作,方法是僅選擇包含來自 B 的數據的列。對於所有國家/地區的完整 dataframe,我不能這樣做,因為在某些情況下它會用 dataframe 中前一個國家的值填寫一個國家的開始年份。
這是數據排列的一個最小示例(請記住,實際數據中有 190 個國家和 9282 個觀測值):
country <- c("Austria","Austria","Austria","Austria","Austria",
"Belgium","Belgium","Belgium","Belgium","Belgium")
year <- c("1999","2000","2001","2002","2003",
"1999","2000","2001","2002","2003")
a1 <- c(5,4,NA,4,3,6,2,9,NA,7)
a2 <- c(45,53,57,51,33,37,12,48,55,41)
b1 <- c(NA,"A",NA,NA,NA,NA,NA,"B",NA,"C")
b2 <- c(NA,7,NA,NA,NA,NA,NA,5,NA,7)
df <- data.frame(country,year,a1,a2,b1,b2)
國家 | 年 | a1 | a2 | b1 | b2 |
---|---|---|---|---|---|
奧地利 | 1999 | 5 | 45 | 不適用 | 不適用 |
奧地利 | 2000 | 4 | 53 | 一個 | 7 |
奧地利 | 2001年 | 不適用 | 57 | 不適用 | 不適用 |
奧地利 | 2002年 | 4 | 51 | 不適用 | 不適用 |
奧地利 | 2003年 | 3 | 33 | 不適用 | 不適用 |
比利時 | 1999 | 6 | 37 | 不適用 | 不適用 |
比利時 | 2000 | 2 | 12 | 不適用 | 不適用 |
比利時 | 2001年 | 9 | 48 | 乙 | 5 |
比利時 | 2002年 | 不適用 | 55 | 不適用 | 不適用 |
比利時 | 2003年 | 7 | 41 | C | 7 |
這是我想要制作的:
國家 | 年 | a1 | a2 | b1 | b2 |
---|---|---|---|---|---|
奧地利 | 1999 | 5 | 45 | 不適用 | 不適用 |
奧地利 | 2000 | 4 | 53 | 一個 | 7 |
奧地利 | 2001年 | 不適用 | 57 | 一個 | 7 |
奧地利 | 2002年 | 4 | 51 | 一個 | 7 |
奧地利 | 2003年 | 3 | 33 | 一個 | 7 |
比利時 | 1999 | 6 | 37 | 不適用 | 不適用 |
比利時 | 2000 | 2 | 12 | 不適用 | 不適用 |
比利時 | 2001年 | 9 | 48 | 乙 | 5 |
比利時 | 2002年 | 不適用 | 55 | 乙 | 5 |
比利時 | 2003年 | 7 | 41 | C | 7 |
在示例中,簡單地使用 tidy::fill 將導致比利時 1999 年和 2000 年的值不正確,因為它將填充來自奧地利的值。
正如Peace Wang 在評論中建議的那樣,您只需要group_by(country)
。 您可以利用tidy-select
專門fill
df B 中的列。
library(tidyverse)
country <- c("Austria","Austria","Austria","Austria","Austria",
"Belgium","Belgium","Belgium","Belgium","Belgium")
year <- c("1999","2000","2001","2002","2003",
"1999","2000","2001","2002","2003")
a1 <- c(5,4,NA,4,3,6,2,9,NA,7)
a2 <- c(45,53,57,51,33,37,12,48,55,41)
b1 <- c(NA,"A",NA,NA,NA,NA,NA,"B",NA,"C")
b2 <- c(NA,7,NA,NA,NA,NA,NA,5,NA,7)
df <- data.frame(country,year,a1,a2,b1,b2)
df %>%
group_by(country) %>%
arrange(year) %>%
fill(starts_with("b"), .direction = "down") %>%
arrange(country)
#> # A tibble: 10 x 6
#> # Groups: country [2]
#> country year a1 a2 b1 b2
#> <chr> <chr> <dbl> <dbl> <chr> <dbl>
#> 1 Austria 1999 5 45 <NA> NA
#> 2 Austria 2000 4 53 A 7
#> 3 Austria 2001 NA 57 A 7
#> 4 Austria 2002 4 51 A 7
#> 5 Austria 2003 3 33 A 7
#> 6 Belgium 1999 6 37 <NA> NA
#> 7 Belgium 2000 2 12 <NA> NA
#> 8 Belgium 2001 9 48 B 5
#> 9 Belgium 2002 NA 55 B 5
#> 10 Belgium 2003 7 41 C 7
由代表 package (v0.3.0) 於 2021 年 12 月 26 日創建
我認為組country
中的locf
(最后一次觀察結轉)nafill 方法是您想要的。
library(data.table)
df = setDT(df)
cols = c("b1","b2")
df[,(cols):= lapply(.SD, zoo::na.locf, na.rm = FALSE),
.SDcols = cols,
by = .(country)]
# data.table::nafill now can only process numeric columns, e.g.
# df[, b2 := nafill(b2, type = c("locf"), by = .(country)]
你可以打開黑匣子然后做
toIm <- c("b1", "b2")
do.call(rbind, c(by(dat, dat$country, \(z) {
z[toIm] <- lapply(z[toIm], \(y) {
unlist(by(y, cumsum(!is.na(y)), \(x)
by(x, cumsum(!is.na(x)), \(w) rep(w[1], length(w)))))
})
z
}), make.row.names=F))
# country year a1 a2 b1 b2
# 1 Austria 1999 5 45 <NA> NA
# 2 Austria 2000 4 53 A 7
# 3 Austria 2001 NA 57 A 7
# 4 Austria 2002 4 51 A 7
# 5 Austria 2003 3 33 A 7
# 6 Belgium 1999 6 37 <NA> NA
# 7 Belgium 2000 2 12 <NA> NA
# 8 Belgium 2001 9 48 B 5
# 9 Belgium 2002 NA 55 B 5
# 10 Belgium 2003 7 41 C 7
注: R version 4.1.2 (2021-11-01)
數據:
dat <- structure(list(country = c("Austria", "Austria", "Austria", "Austria",
"Austria", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium"
), year = c(1999L, 2000L, 2001L, 2002L, 2003L, 1999L, 2000L,
2001L, 2002L, 2003L), a1 = c(5L, 4L, NA, 4L, 3L, 6L, 2L, 9L,
NA, 7L), a2 = c(45L, 53L, 57L, 51L, 33L, 37L, 12L, 48L, 55L,
41L), b1 = c(NA, "A", NA, NA, NA, NA, NA, "B", NA, "C"), b2 = c(NA,
7L, NA, NA, NA, NA, NA, 5L, NA, 7L)), class = "data.frame", row.names = c(NA,
-10L))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.