Remplissez les valeurs manquantes dans un data.table en utilisant le taux de croissance par catégorie

voix
3

J'ai incomplètes (temps) série où je voudrais combler les valeurs manquantes en utilisant les valeurs disponibles récentes et les taux de croissance d'une autre série, par catégorie (pays). Catégories, valeurs manquantes ne sont pas la même longueur. Cela nécessite l'application d'une fonction d'une variable séquentielle: d'abord je dois prendre le dernier point de données disponibles (qui peut être partout) et le diviser par 1 + taux de croissance, puis passer à l'autre point de données et faire la même chose.

Exemple ensemble de données et du résultat souhaité:

require(data.table)
DT_desired<-data.table(category=c(rep(A,4),rep(B,4)),
           year=2010:2013,
           grwth=c(NA,.05,0.1,0,NA,0.1,0.15,0.2))
DT_desired[,values:=c(cumprod(c(1,DT_desired[category==A&!is.na(grwth),grwth]+1)),cumprod(c(1,DT_desired[category==B&!is.na(grwth),grwth]+1)))]

DT_example <- copy(DT_desired)[c(1,2,3,5),values:=NA]

Ce que j'essayé: vous pouvez le faire par une boucle, mais qui est inefficace et découragée R. Je suis venu à aimer l'efficacité de data.table, et je le ferais de préférence de cette façon. J'ai essayé la fonction de changement de table de données, qui remplit une seule valeur manquante (ce qui est logique car il tente d'exécuter en même temps, je suppose que, quand le reste manque la valeur précédente).

DT_example[,values:=ifelse(is.na(values),shift(values,type = lead)/(1+shift(grwth,type = lead)),values),by=category]

Je déduis d'autres messages que vous pouvez probablement le faire avec la fonction rollapply du paquet zoo, mais je viens de recevoir le sentiment que je devrais être en mesure de le faire dans le tableau de données sans autre paquet supplémentaire, et que la solution est relativement simple et élégant, juste je ne suis pas assez expérimenté pour le trouver.

Cela peut très bien être un double et désolé si je ne l'ai pas remarqué le poste approprié, mais rien de ce que j'ai trouvé fait exactement ce que je veux.

Créé 27/11/2018 à 15:08
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Je ne sais pas si cela a été résolu en dehors de SO, mais il a attiré mon attention , l'autre jour. Je ne l' avais pas écrit CRPP depuis longtemps et pensé que ce serait une bonne pratique. Je sais que vous cherchez natif data.tablesolution, alors ne hésitez pas à prendre ou à laisser:

Contenu du foo.cppfichier:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector fillValues(NumericVector vals, NumericVector gRates){

  int n = vals.size();
  NumericVector out(n);

  double currentValue   = vals[n - 1];
  double currentGrowth  = gRates[n - 1];

  // initial assignment
  out[n - 1] = currentValue;

  for(int i = n - 2; i >= 0; i--){

    if(NumericVector::is_na(vals[i])){
      // If val[i] is na, we need prior values to populate it
      if(!((currentValue || currentValue == 0) && (currentGrowth || currentGrowth == 0))){
        // We need a currentValue and currentGrowth to base growth rate on, throw error
        Rcpp::stop("NaN Values for rates or value when needed actual value");
      } else {
        // Update value
        out[i] = currentValue / (1 + currentGrowth);
      }
    } else {
      out[i] = vals[i];
    }

    // update
    currentValue = out[i];
    if(!NumericVector::is_na(gRates[i])){
      currentGrowth = gRates[i];
    }
  }

  return out;
}

/*** R
require(data.table)
DT_desired<-data.table(category=c(rep("A",4),rep("B",4)),
                       year=2010:2013,
                       grwth=c(NA,.05,0.1,0,NA,0.1,0.15,0.2))

DT_desired[,values:=c(cumprod(c(1,DT_desired[category=="A"&!is.na(grwth),grwth]+1)),cumprod(c(1,DT_desired[category=="B"&!is.na(grwth),grwth]+1)))]

DT_example <- copy(DT_desired)[c(1,2,3,5),values:=NA]

DT_desired[]
DT_example[]

DT_example[, values:= fillValues(values, grwth)][]
*/

Ensuite, exécutez:

> Rcpp::sourceCpp('foo.cpp')

# Removed output that created example data

> DT_desired[]
   category year grwth values
1:        A 2010    NA  1.000
2:        A 2011  0.05  1.050
3:        A 2012  0.10  1.155
4:        A 2013  0.00  1.155
5:        B 2010    NA  1.000
6:        B 2011  0.10  1.100
7:        B 2012  0.15  1.265
8:        B 2013  0.20  1.518

> DT_example[]
   category year grwth values
1:        A 2010    NA     NA
2:        A 2011  0.05     NA
3:        A 2012  0.10     NA
4:        A 2013  0.00  1.155
5:        B 2010    NA     NA
6:        B 2011  0.10  1.100
7:        B 2012  0.15  1.265
8:        B 2013  0.20  1.518

> DT_example[, values:= fillValues(values, grwth)][]
   category year grwth values
1:        A 2010    NA  1.000
2:        A 2011  0.05  1.050
3:        A 2012  0.10  1.155
4:        A 2013  0.00  1.155
5:        B 2010    NA  1.000
6:        B 2011  0.10  1.100
7:        B 2012  0.15  1.265
8:        B 2013  0.20  1.518

Notez que ce reflue vers l'avant, et suppose que vous voulez commencer par le plus récent enregistrement et de travailler à des enregistrements de plus en arrière. Il suppose également que votre ensemble de données est triée.

Créé 29/11/2018 à 16:44
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more