11
votes

Données divisées.Table

J'ai une donnée de données que je veux diviser en deux. Je fais cela comme suit: xxx

mais si je veux à quelque chose comme ça comme une étape suivante xxx

i Obtenir l'avertissement suivant message.

Message d'avertissement: dans [. Datable.table (SDT [[1]] , : = (c, .n), by = a): Invalide .internal.elfref a détecté et fixé en prenant une copie de la Table entière, de sorte que: = peut ajouter cette nouvelle colonne par référence. Un bronzage Point antérieur, cette carte a été copiée par R. Évitez la clé <-, noms <- et ATTER <- qui en est actuellement (et curieusement) peut copier l'ensemble données.Table. Utilisez le jeu * Syntaxe plutôt que pour éviter la copie: Set Tkey (), setNames () et Seattr (). En outre, la liste (DT1, DT2) copiera l'ensemble du DT1 et DT2 (Liste de R (liste R () Copie des objets nommés), utilisez la réfliste () à la place si nécessaire (à mettre en œuvre). Si ce message ne vous aide pas, s'il vous plaît Rapport à l'aide de DataTable afin que la cause de la racine puisse être corrigée.

Je me demande simplement s'il y a une meilleure façon de fractionnement de la table afin qu'elle soit plus efficace (et ne recevrait pas ce message)?


5 commentaires

Pourquoi voulez-vous diviser les données.Table en premier lieu? Nous fractionnez en créant une liste, donc l'avertissement traite de la raison pour laquelle la copie a eu lieu


Je crée deux ensembles pour mes expériences, sur la base d'une fraction de temps.


Je suis curieux de savoir ce que le .n signifie dans ce cas?


@ Simono101 .n n'est que le nombre de lignes pour les groupes.


Dans 1.9.7, la méthode divisée de datably.Table, votre code fonctionnera simplement.


3 Réponses :


11
votes

Cela fonctionne dans le V1.8.7 (et peut également fonctionner dans V1.8.6):

> sdt = lapply(split(1:nrow(dt), dt$b==2), function(x)dt[x])
> sdt
$`FALSE`
   a b
1: 1 1
2: 2 1

$`TRUE`
   a b
1: 3 2
2: 3 2

> sdt[[1]][,c:=.N,by=a]     # now no warning
> sdt
$`FALSE`
   a b c
1: 1 1 1
2: 2 1 1

$`TRUE`
   a b
1: 3 2
2: 3 2


4 commentaires

Je ne comprends pas tout à fait pourquoi il dit invalide .internal.elfref comme lorsque je fais des attributs (sdt [[1]]) $. Interne.elfref , la valeur semble être identique à celui de dt (et idem sur dt2 <- copier (dt) ) .. toutes les pensées?


@Arun exactement, c'est pourquoi c'est invalide. C'est censé pointer sur lui-même lorsqu'il est valide. Si vous regardez .Internal (inspectez (SDT [[1]])) Vous devez voir que son adresse de pointeur est différente (une copie a été prise). C'est ce que .internal.elfref est conçu pour détecter. Le problème avec la copie n'est pas tellement la copie en soi, mais que lorsque R est-ce que cela copie, il ne maintient pas le vecteur sur le vecteur sur des points de colonne. D'où l'avertissement lorsque : = essaie d'ajouter une nouvelle colonne (elle doit à nouveau sur-allouer) au cas où vous auriez deux liaisons sur le même objet. Tous corrects et destinés.


@Arun pour que l'avertissement essaie de dire: ne Base :: Split Trouvez une autre solution, telle que ma réponse, pour faire la scission.


@Arun Il y a aussi data.able.table ::: Selfrefok (sdt [[1]]) qui vérifie si .Internal.elfref est valide ou non. Retourne 0/1. Délibérément pas exporté car il est juste destiné à avoir débogué / inspecter.



4
votes

Je cherchais un moyen de faire une scission de données.table, je suis tombé sur cette ancienne question.

Une fraction est ce que vous voulez faire, et la mesure "par" approche "par" n'est pas pratique . P>

En réalité, vous pouvez facilement faire votre fractionnement à la main avec des données de données. Seules les instructions et fonctionnent très efficacement: P>

SplitDataTable <- function(dt,attr) {
  boundaries=c(0,which(head(dt[[attr]],-1)!=tail(dt[[attr]],-1)),nrow(dt))
  return(
    mapply(
      function(start,end) {dt[start:end,]},
      head(boundaries,-1)+1,
      tail(boundaries,-1),
      SIMPLIFY=F))
}


1 commentaires

Bonne idée, mais ceci est plus lent que d'utiliser Split () sur mes données (nrow = 25000, une portée de groupes)



3
votes

Comme indiqué ci-dessus (@jangorecki), le package data.Table code> a déjà sa propre fonction pour la division. Dans ce cas simplifié, nous pouvons utiliser:

> dt <- data.table(a = c(1, 2, 3, 3), b = c(1, 1, 2, 2))
> split(dt, by = "b")
$`1`
   a b
1: 1 1
2: 2 1

$`2`
   a b
1: 3 2
2: 3 2


0 commentaires