Экстраполировать строки за последний год, доступные до данного года - PullRequest
0 голосов
/ 16 октября 2019

У меня есть следующие данные:

library(data.table)  
df <- fread(
    "A   B  C  D  E  F  iso   year   
    0   A   NA  1  NA  NA  NLD   2009   
    1   Y   NA  2  NA  NA  NLD   2010   
    0   Q   NA  3  NA  NA  AUS   2011   
    1   NA  NA  4  NA  NA  AUS   2012 
    0   0   NA  7  NA  NA  NLD   2011  
    0   NA  1   NA  1  NA  ECU   2009   
    1   NA  0   NA  2  0   ECU   2010    
    1   NA  0   NA  2  0   ECU   2011    
    0   NA  0   NA  3  2   BRA   2011   
    1   NA  0   NA  4  NA  BRA   2012",
    header = TRUE
)

Я хочу экстраполировать для каждой страны запись прошлого года в наборе данных до определенного года. Например, я хочу использовать последний год для каждой страны в df (NLD = 2011, AUS = 2012, BRA = 2012, ECU = 2011), чтобы создавать записи до 2014 года. Другими словами, я хотел бысделайте дубликаты этих записей, но с измененными годами, за последний доступный год до 2014 года.

Желаемый результат:

library(data.table)  
df <- fread(
    "A   B  C  D  E  F  iso   year   
    0   A   NA  1  NA  NA  NLD   2009   
    1   Y   NA  2  NA  NA  NLD   2010   
    0   Q   NA  3  NA  NA  AUS   2011   
    1   NA  NA  4  NA  NA  AUS   2012
    1   NA  NA  4  NA  NA  AUS   2013 
    1   NA  NA  4  NA  NA  AUS   2014    
    0   0   NA  7  NA  NA  NLD   2011  
    0   0   NA  7  NA  NA  NLD   2012 
    0   0   NA  7  NA  NA  NLD   2013 
    0   0   NA  7  NA  NA  NLD   2014 
    0   NA  1   NA  1  NA  ECU   2009   
    1   NA  0   NA  2  0   ECU   2010   
    0   NA  0   NA  3  0   BRA   2011   
    1   NA  0   NA  4  0   BRA   2011   
    1   NA  0   NA  2  0   ECU   2011   
    1   NA  0   NA  2  0   ECU   2012
    1   NA  0   NA  2  0   ECU   2013 
    1   NA  0   NA  2  0   ECU   2014    
    0   NA  0   NA  3  2   BRA   2011   
    1   NA  0   NA  4  NA  BRA   2012
    1   NA  0   NA  4  NA  BRA   2013
    1   NA  0   NA  4  NA  BRA   2014",
    header = TRUE
)

Но я не знаю, с чего начать. Какой самый простой способ сделать это?

РЕДАКТИРОВАТЬ: при тестировании на реальных данных, я заметил, что упустил один аспект набора данных при формулировке вопроса. В наборе точных данных есть еще один уникальный аспект (столбец A) в ряду, кроме года.

library(data.table)  
df <- fread(
    "A   B  C  D  E  F  iso   year   
    1   A   NA  1  NA  NA  NLD   2009   
    1   Y   NA  2  NA  NA  NLD   2010   
    1   Q   NA  3  NA  NA  AUS   2011   
    1   NA  NA  4  NA  NA  AUS   2012 
    1   0   NA  7  NA  NA  NLD   2011  
    1   NA  1   NA  1  NA  ECU   2009   
    1   NA  0   NA  2  0   ECU   2010    
    1   NA  0   NA  2  0   ECU   2011    
    1   NA  0   NA  3  2   BRA   2011   
    1   NA  0   NA  4  NA  BRA   2012
    0   A   NA  1  NA  NA  NLD   2009   
    0   Y   NA  2  NA  NA  NLD   2010   
    0   Q   NA  3  NA  NA  AUS   2011   
    0   NA  NA  4  NA  NA  AUS   2012 
    0   0   NA  7  NA  NA  NLD   2011  
    0   NA  1   NA  1  NA  ECU   2009   
    0   NA  0   NA  2  0   ECU   2010    
    0   NA  0   NA  2  0   ECU   2011    
    0   NA  0   NA  3  2   BRA   2011   
    0   NA  0   NA  4  NA  BRA   2012",
    header = TRUE
)

Я попытался адаптировать результат Ронака в этом отношении:

df <- df %>%
  group_by(iso, A) %>%
  slice(c(1:n(), rep(n(), 2014 - last(year)))) %>%
  mutate(year = first(year):2014)
###
df <- df %>%
  #If not arranged by year
  arrange(iso, year, A)
  group_by(iso) %>%
  complete(year = seq(min(year), 2014)) %>%
  fill(B:F)

Верхний код работает, но на моих реальных данных выдает ошибку:

Error: Column `year` must be length 18 (the group size) or one, not 21

Нижняя опция выдает следующую ошибку применительно к примеру:

Error in group_by(iso) : object 'iso' not found

1 Ответ

2 голосов
/ 16 октября 2019

Чтобы реплицировать последнюю строку, мы можем group_by iso и повторить последнюю строку в каждой группе

df %>%
  group_by(iso) %>%
  slice(c(1:n(), rep(n(), 2014 - last(year)))) %>%
  mutate(year = first(year):2014)

Для обновленных данных, где year значения повторяются

df %>%
  group_by(iso) %>%
  mutate(row = row_number()) %>%
  slice(row, rep(n(), 2014 - last(year))) %>%
  mutate(year = c(year[1:max(row)], year[max(row)] + 1:(2014 - year[max(row)]))) %>%
  select(-row)

#       A B         C     D     E     F iso    year
#   <int> <chr> <int> <int> <int> <int> <chr> <int>
# 1     1 Q        NA     3    NA    NA AUS    2011
# 2     1 NA       NA     4    NA    NA AUS    2012
# 3     0 Q        NA     3    NA    NA AUS    2011
# 4     0 NA       NA     4    NA    NA AUS    2012
# 5     0 NA       NA     4    NA    NA AUS    2013
# 6     0 NA       NA     4    NA    NA AUS    2014
# 7     1 NA        0    NA     3     2 BRA    2011
# 8     1 NA        0    NA     4    NA BRA    2012
# 9     0 NA        0    NA     3     2 BRA    2011
#10     0 NA        0    NA     4    NA BRA    2012
# … with 20 more rows
...