162 votes

Comment supprimer une ligne par référence dans R data.table?

Ma question est liée à l'affectation par référence contre la copie des données.table. Je veux savoir si on peut supprimer des lignes de référence, semblable à

DT[,someCol:=NULL]

Je veux savoir à propos de

DT[someRow:=NULL, ]

Je pense qu'il y a une bonne raison pour expliquer pourquoi cette fonction n'existe pas, de sorte que vous pourriez peut-être juste le point de sortir une bonne alternative à l'habituel copie approche, comme ci-dessous. En particulier, aller avec mes favoris à partir de l'exemple(des données.table),

DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
     x y v
[1,] a 1 1
[2,] a 3 2
[3,] a 6 3
[4,] b 1 4
[5,] b 3 5
[6,] b 6 6
[7,] c 1 7
[8,] c 3 8
[9,] c 6 9

dire que je veux supprimer la première ligne à partir de ces données.table. Je sais que je peux le faire

DT = DT[-1, ]

mais souvent, nous voulons éviter que, parce que nous sommes de la copie de l'objet (et qui a besoin d'environ 3*N de mémoire, si N objet.taille(DT), comme l'a souligné ici. Maintenant, j'ai trouvé set(DT,i,j,valeur). Je sais comment définir des valeurs spécifiques (comme ici: ensemble de toutes les valeurs dans les lignes 1 et 2 et les colonnes 2 et 3 à zéro)

set(DT,1:2,2:3,0) 
DT
     x y v
[1,] a 0 0
[2,] a 0 0
[3,] a 6 3
[4,] b 1 4
[5,] b 3 5
[6,] b 6 6
[7,] c 1 7
[8,] c 3 8
[9,] c 6 9

mais comment puis-je effacer les deux premières lignes, dites? Faire

set(DT,1:2,1:3,NULL)

définit l'ensemble de la DT à NULL.

Mes connaissances SQL est très limité, de sorte que vous les gars me dire: compte tenu des données.le tableau utilise la technologie SQL, est-il équivalent à la commande SQL

DELETE FROM table_name
WHERE some_column=some_value

dans les données.de la table?

129voto

Matt Dowle Points 20936

Bonne question. data.table ne pouvez pas supprimer des lignes de référence encore.

data.table pouvez ajouter et supprimer des colonnes par référence car il alloue le vecteur colonne des pointeurs, comme vous le savez. Le plan est de faire quelque chose de similaire pour les lignes et permettre rapide, insert et delete. Une ligne supprimer utiliserait memmove C de faire bouger les articles (dans chaque colonne) après les lignes supprimées. La suppression d'une ligne dans le milieu de la table serait encore tout à fait inefficace par rapport à une ligne de magasin de base de données tels que SQL, qui est plus adapté pour une rapide insérer et supprimer des lignes, partout où ces lignes sont dans le tableau. Mais encore, il serait beaucoup plus rapide que la copie d'un nouveau grand objet sans lignes supprimées.

D'autre part, puisque les vecteurs colonnes seraient plus affectés, les lignes peuvent être insérées (et supprimer) à la fin, instantanément; par exemple, un temps de croissance de la série.

29voto

vc273 Points 141

L’approche que j’ai choisie pour que la mémoire soit utilisée de la même façon que la suppression sur place consiste à sous-définir une colonne à la fois et à la supprimer. pas aussi rapidement qu'une solution C memmove appropriée, mais l’utilisation de la mémoire est tout ce qui m’intéresse ici. quelque chose comme ça:

 DT = data.table(col1 = 1:1e6)
cols = paste0('col', 2:100)
for (col in cols){ DT[, col := 1:1e6, with = F] }
keep.idxs = sample(1e6, 9e5, FALSE) # keep 90% of entries
DT.subset = data.table(col1 = DT[['col1']][keep.idxs]) # this is the subsetted table
for (col in cols){
  DT.subset[, col := DT[[col]][keep.idxs], with = F]
  DT[, col:= NULL, with = F] #delete
}
 

4voto

BondedDust Points 105234

Au lieu de cela ou si vous essayez de définir NULL, essayez de définir NA (correspondant au type NA pour la première colonne).

 set(DT,1:2, 1:3 ,NA_character_)
 

-2voto

Edwin Points 610

Étant donné que la ligne que vous souhaitez supprimer a une clé unique sur une ou plusieurs colonnes, vous pouvez tout sélectionner sauf cette ligne et écraser l'objet avec celui-ci.

 ex_dat <- data.table(
  year = rep(2009:2014,3),
  category = rep(letters[1:3], each = 3))
nrow(ex_dat) # 18

ex_dat <- ex_dat[!(year == 2011 & category == "a"), ]
nrow(ex_dat) # 17
 

-12voto

library(sqldf)

# request

sqldf("DELETE FROM table_name tn WHERE tn.field_name = your_criteria")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X