2010-04-16 1 views
1

J'essaye de transformer mon data.frame en calculant le log-differences de chaque colonne et en contrôlant pour les rangées id. Donc essentiellement j'aime calculer les taux de croissance pour la variable de chaque ID. Voici donc un df aléatoire avec une colonne id, une période de temps Colum p et trois colonnes variables:Calcul des taux de croissance en appliquant les différences de log

df <- data.frame (id = c("a","a","a","c","c","d","d","d","d","d"), 
        p = c(1,2,3,1,2,1,2,3,4,5), 
        var1 = rnorm(10, 5), 
        var2 = rnorm(10, 5), 
        var3 = rnorm(10, 5) 
       ) 
df 
    id p  var1  var2  var3 
1  a 1 5.375797 4.110324 5.773473 
2  a 2 4.574700 6.541862 6.116153 
3  a 3 3.029428 4.931924 5.631847 
4  c 1 5.375855 4.181034 5.756510 
5  c 2 5.067131 6.053009 6.746442 
6  d 1 3.846438 4.515268 6.920389 
7  d 2 4.910792 5.525340 4.625942 
8  d 3 6.410238 5.138040 7.404533 
9  d 4 4.637469 3.522542 3.661668 
10 d 5 5.519138 4.599829 5.566892 

Maintenant, je l'ai écrit une fonction qui fait exactement ce que je veux, mais je devais prendre un détour qui est éventuellement inutile et peut être retiré. Cependant, en quelque sorte je ne suis pas en mesure de localiser le raccourci. Voici la fonction et la sortie pour la trame de données affiché:

fct.logDiff <- function (df) { 
df.log <- dlply (df, "code", function(x) data.frame (p = x$p, log(x[, -c(1,2)]))) 
list.nalog <- llply (df.log, function(x) data.frame (p = x$p, rbind(NA, sapply(x[,-1], diff)))) 
ldply (list.nalog, data.frame) 
} 

fct.logDiff(df) 
    id p  var1  var2  var3 
1  a 1   NA   NA   NA 
2  a 2 -0.16136569 0.46472004 0.05765945 
3  a 3 -0.41216720 -0.28249264 -0.08249587 
4  c 1   NA   NA   NA 
5  c 2 -0.05914281 0.36999681 0.15868378 
6  d 1   NA   NA   NA 
7  d 2 0.24428771 0.20188025 -0.40279188 
8  d 3 0.26646102 -0.07267311 0.47041227 
9  d 4 -0.32372771 -0.37748866 -0.70417351 
10 d 5 0.17405309 0.26683625 0.41891802 

Le problème est dû à la valeur ajoutée NA -rows. Je ne veux pas réduire le cadre et le réduire, ce qui serait automatiquement fait par la fonction diff(). Donc j'avais 10 lignes dans mon cadre d'origine et je garde le même nombre de lignes après la transformation. Afin de garder la même longueur, j'ai dû ajouter quelques NAs. J'ai fait un détour en transformant le data.frame en une liste, en ajoutant le NAs à la première ligne de chaque identifiant, et ensuite en transformant la liste en data.frame. Cela a l'air fastidieux.

Des idées pour éviter la transformation de classe data.frame-list-data.frame et optimiser la fonction?

Répondre

2

Que pensez-vous de cela?

nadiff <- function(x, ...) c(NA, diff(x, ...)) 
ddply(df, "code", colwise(nadiff, c("var1", "var2", "var3"))) 
+0

@hadley agréable, fonctionne très bien! J'ai toujours essayé de combiner l'une des fonctions d'application avec l'une des fonctions du paquet de base. et je n'ai eu qu'à jeter un autre coup d'oeil dans votre paquet de plyr. Je n'ai pas utilisé la fonction colwise avant. Merci! – mropa

Questions connexes