Как легко заполнить пропущенные значения df1 (в момент времени t), используя соотношение df2 (t) / df2 (t-1)? - PullRequest
0 голосов
/ 28 июня 2018

Существует два кадра данных, в первом отсутствуют пропущенные значения, во втором нет пропущенных значений. Правила таковы:

1: для year(t) of df1, если значение year(t) отсутствует, используется значение year(t-1)*ratio. ratio = value of year(t) / value of year(t-1) из df2

2: В df1 нет данных как в 2012, так и в 2013 году, но нам нужно только вменять пропущенные данные за 2012 год, то есть через год после самых последних данных. Нам не нужно вменять в течение всех лет.

Мой путь немного глуп. У кого-нибудь могут быть лучшие способы исправить это?

data2 = data.frame('population by age' = seq(5, 8, by = 1), 
                     '2008' = c(145391,
                                140621,
                                136150,
                                131944
                     ),  
                     '2009' = c(148566,
                                143943,
                                139367,
                                135083
                     ), 
                     '2010' = c(152330,
                                147261,
                                142555,
                                138172
                     ),  
                     '2011' = c(156630,
                                151387,
                                146491,
                                141905
                     ),
                     '2012' = c(133545,
                                129737,
                                126124,
                                122678
                      ),
                     '2013' = c(119397,
                                116093,
                                112666,
                                109174)) 


  data1 <- data.frame('grade' = seq(1, 4, by = 1), 
                                     '2008'= c(218701,
                                               NA,
                                               142190,
                                               NA),
                                     '2009' = c(NA,
                                                196398,
                                                155033,
                                                NA),
                                     '2010' = c(212512,
                                                NA,
                                                176268,
                                                143699),
                                     '2011' = c(218529,
                                                198933,
                                                NA,
                                                159103),
                      '2012' = c(NA,
                                 NA,
                                 NA,
                                 NA),
                      '2013' = c(NA,
                                 NA,
                                 NA,
                                 NA)
                      )

Ответы [ 2 ]

0 голосов
/ 29 июня 2018
# Find the column number of the last column with non-na value
  ind <- !is.na(data1)
  t1 <- tapply(data1[ind], col(data1)[ind],tail, 1)
  last_non_na_col <- as.numeric(tail(unlist(dimnames(t1)), n = 1))

  for (i in 1:nrow(data1)) {
    for (j in 3:(last_non_na_col+1)) { 
      if (is.na(data1[i,j])) {
        data1[i,j] = data1[i,j-1]*data2[i,j]/data2[i,j-1]
      }
    }
  }

Вывод будет таким. И это именно то, что я хочу.

 > data1
    grade  X2008    X2009    X2010    X2011    X2012 X2013
1     1 218701 223476.9 212512.0 218529.0 186321.0    NA
2     2     NA 196398.0 200925.1 198933.0 170483.4    NA
3     3 142190 155033.0 176268.0 181134.8 155951.2    NA
4     4     NA       NA 143699.0 159103.0 137545.8    NA
0 голосов
/ 29 июня 2018

Сначала создайте новый фрейм данных со значениями для замены. Я использую пакет data.table, чтобы сделать это; вы можете попробовать решение, используя dplyr / tidyr, если хотите. Затем замените NA в data1. Поскольку нет данных для каждого класса и года, все еще будут НС. Поэтому поместите все в цикл while:

library(data.table)

while( anyNA(data1[ncol(data1)]) ) {
  data1.sub <- copy(data1)
  for( t in 3:ncol(data1.sub) ) set( data1.sub, j = t, value = data1[[t-1]]*(data2[[t]]/data2[[t-1]]) )
  data1[ is.na(data1) ] <- data1.sub[ is.na(data1) ]
}

Я использую 3: ncol (), потому что до X2008 нет информации. Вот результат:

> data1
  grade  X2008    X2009    X2010    X2011    X2012 X2013
1     1 218701 223476.9 212512.0 218529.0 186321.0 166581.8
2     2     NA 196398.0 200925.1 198933.0 170483.4 152554.2
3     3 142190 155033.0 176268.0 181134.8 155951.2 139310.5
4     4     NA       NA 143699.0 159103.0 137545.8 122405.2

Тот же результат будет достигнут с использованием кода в вашем ответе , если вы используете цикл для всех столбцов после X2008:

for (i in 1:nrow(data1)) {
  for (j in 3:ncol(data1)) { 
    if (is.na(data1[i,j])) data1[i,j] = data1[i,j-1]*data2[i,j]/data2[i,j-1]
} }
...