10
votes

R performance avec redémarrage de données

J'essaie de remodeler un cadre de données dans R et il semble avoir des problèmes en utilisant les moyens recommandés de le faire. La trame de données a la structure suivante: xxx

VALTYPE est une chaîne et est un facteur avec seulement 2 valeurs (disons type1 et < code> type2 ). Je dois le transformer en la trame de données suivante ("largeur" ​​transpose) basée sur l'identifiant et les dates communes: xxx

La trame de données comporte plus de 4 500 000 observations (bien que environ 70 % de valeur s sont na / code>). La machine est une station de travail Linux basée sur Intel avec 4 Go de RAM. Chargement des données (à partir d'un fichier RData compressé) dans un processus RD Fresh R, il reproche à environ 250 Mo, ce qui laisse clairement beaucoup d'espace pour remodeler.

Ce sont mes expériences jusqu'à présent: < ul>

  • Utilisation de vanille Remodape () Méthode:

    tbl2 <- remodele (tbl, direction = "large", idvar = c ("id", "date1", "date2"), TIMEVAR = "VALTYPE");

    résultat: Erreur: impossible d'allouer le vecteur de taille 4.8 Go

    • en utilisant couler () méthode de Remodape package:

      Tbl2 <- Cast (TBL, ID + Date1 + Date2 ~ Valtalpe);

      résultat: r Process consume tous les béliers sans fin en vue. Dû tuer le processus finalement.

      • en utilisant par () et fusion () :

        sp <- par (TBL [C (1,2,3,5)], TBL $ VALTYPE, fonction (x) x); tbl <- fusion (SP [["type1"]], SP [["type2"]]], par = c ("id", "date1", "date2"), tout = vrai, tri = true);

        Résultat: fonctionne bien, bien que cela ne soit pas très élégant et infaillible (c'est-à-dire qu'il va casser si plus de types sont ajoutés).

        Pour ajouter une insulte à une blessure, l'opération en question peut Soyez trivialement atteint dans environ 3 lignes d'awk ou de Perl (et avec pratiquement tout RAM utilisé). Donc, la question est la suivante: qu'est-ce qui est un meilleur moyen de faire cette opération en utilisant les méthodes recommandées sans consommer de toutes les béliers disponibles?


  • 0 commentaires

    3 Réponses :


    1
    votes

    Un astuce utile consiste à combiner les variables d'identifiant dans un vecteur de caractère puis à faire le remodelage.

    tbl$NEWID <- with(tbl, paste(ID, DATE1, DATE2, sep=";"))
    tbl2 <- recast(tbl2, NEWID ~ VALTYPE, measure.var="VALUE")
    


    1 commentaires

    NOPE, en utilisant recast () montre le même problème que possible avec Cast () méthode ci-dessus - Le processus s'est passé sur 5 Go de mémoire virtuelle, donc je l'ai tué après environ 1 heure.



    1
    votes

    Qu'en est-il de le faire de manière non r. Je suppose que vous avez une ligne de type1 et une ligne de type2 pour chaque valeur d'ID, date1, date2? Puis triez le Dataframe par ces variables et écrivez un gros pour la boucle. Vous pouvez effectuer plusieurs fois des opérations RBind () pour construire la table ou vous pourriez essayer de pré-allouer la table (peut-être) et d'affecter les emplacements Value.type1 et Value.Type2 avec [<-, qui devrait faire l'affectation endroit.

    (Notez que si vous utilisez RBind (), je pense que c'est inefficace si vous avez des variables de facteur, assurez-vous que tout est un personnage!)


    2 commentaires

    Sans rbind et boucles: tbl <- TBL [avec (TBL, ordre (ID, date1, date2, VALTYPE)),]; tbl_out <- TBL [SEQ (1, NROW (TBL), by = 2), - 4]; noms (tbl_out) [4] <- "valeur.type1"; tbl_out $ valeur.type2 <- TBL $ valeur [SEQ (2, NROW (TBL), by = 2)];


    Nous ne pouvons pas vraiment supposer qu'il y a exactement 2 entrées pour chaque identifiant / dates. Cela brisera immédiatement le code de Marek ci-dessus. De plus, il serait encore plus fragile que mon par () / fusion () code dans le corps de la question. Globalement, je n'ai aucun problème avec l'approche de boucle, sauf que je ne comprends pas pourquoi la fonction spécifiquement à cette fin (c'est-à-dire remodele () échoue sur un problème aussi trivial)



    1
    votes

    Peut-être que vous pourriez utiliser la fonction CAT ()?


    0 commentaires