我有以下資料結構,我想在其中逐行插入資料,直到某一年:
require('data.table')
test_dt <- data.table(iso1 = c('BTN', 'IND', 'BGD'),
iso2 = c('AFG', 'AFG', 'AFG'),
year = c(2006, 2003, 2006))
我想出了以下函式,它適用于單行情況,但不適用于一般情況:
interpolate_rows <- function(dt, stop_year = 2008) {
year <- as.integer(dt[, .SD, .SDcols = 'year'])
# If year is less than stop year, fill in observations:
if (year < stop_year) {
time_delta <- seq(year, stop_year)
# Explode bilateral country observation:
dt <- dt[rep(dt[, .I], length(time_delta))]
# Replace year column w/ time_delta sequence:
dt <- dt[, year := time_delta]
}
return(dt)
}
## Output
bar <- interpolate_rows(test_dt[1])
bar
iso1 iso2 year
1: BTN AFG 2006
2: BTN AFG 2007
3: BTN AFG 2008
我想要的是以下內容:
bar <- interpolate_rows(test_dt)
bar
iso1 iso2 year
1: BTN AFG 2006
2: BTN AFG 2007
3: BTN AFG 2008
6: IND AFG 2003
7: IND AFG 2004
8: IND AFG 2005
9: IND AFG 2006
10: IND AFG 2007
11: IND AFG 2008
14: BGD AFG 2006
14: BGD AFG 2007
14: BGD AFG 2008
我知道罪魁禍首很可能是這條線
year <- as.integer(dt[, .SD, .SDcols = 'year']),但我不知道如何用它來代替作業向量解決方案。我試圖在其中嵌套一個lapply()函式interpolate_rows()來提取每個獨特組的年份并使用Map(),但這些都沒有產生有效的解決方案。
任何幫助我指出可行的矢量解決方案的幫助,將不勝感激。
uj5u.com熱心網友回復:
簡單地使用怎么樣by:
test_dt[, .(year = min(year):stop_year), by = .(iso1, iso2)]
# iso1 iso2 year
# 1: BTN AFG 2006
# 2: BTN AFG 2007
# 3: BTN AFG 2008
# 4: IND AFG 2003
# 5: IND AFG 2004
# 6: IND AFG 2005
# 7: IND AFG 2006
# 8: IND AFG 2007
# 9: IND AFG 2008
# 10: BGD AFG 2006
# 11: BGD AFG 2007
# 12: BGD AFG 2008
uj5u.com熱心網友回復:
使用dplyr和tidyr庫的一種方式。
library(dplyr)
library(tidyr)
interpolate_rows <- function(dt, stop_year = 2008) {
dt %>%
group_by(iso1, iso2) %>%
complete(year = year : stop_year) %>%
ungroup
}
interpolate_rows(test_dt)
# iso1 iso2 year
# <chr> <chr> <dbl>
# 1 BGD AFG 2006
# 2 BGD AFG 2007
# 3 BGD AFG 2008
# 4 BTN AFG 2006
# 5 BTN AFG 2007
# 6 BTN AFG 2008
# 7 IND AFG 2003
# 8 IND AFG 2004
# 9 IND AFG 2005
#10 IND AFG 2006
#11 IND AFG 2007
#12 IND AFG 2008
其它的辦法 -
library(data.table)
interpolate_rows <- function(dt, stop_year = 2008) {
vals <- seq(dt$year, stop_year)
dt[rep(1, length(vals))][, year := vals]
}
rbindlist(by(test_dt, seq(nrow(test_dt)), interpolate_rows))
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/324569.html
