Extraction de lignes uniques à partir d'une table de données dans R [dupliquer]

Cette question a déjà une réponse ici:

Je migre des trames de données et des matrices vers des tables de données, mais je n'ai pas trouvé de solution pour extraire les lignes uniques d'une table de données. Je présume qu'il me manque quelque chose à propos de la notation [,J], bien que je ne l'aie pas encore fait trouvé une réponse dans la FAQ et les vignettes d'introduction. Comment puis-je extraire les lignes uniques, sans les convertir en trames de données?

Voici un exemple:

library(data.table)
set.seed(123)
a <- matrix(sample(2, 120, replace = TRUE), ncol = 3)
a <- as.data.frame(a)
b <- as.data.table(a)

# Confirm dimensionality
dim(a) # 40  3
dim(b) # 40  3

# Unique rows using all columns
dim(unique(a))  # 8 3
dim(unique(b))  # 34 3

# Unique rows using only a subset of columns
dim(unique(a[,c("V1","V2")]))   # 4 2
dim(unique(b[,list(V1,V2)]))    # 29 2

Question connexe: ce comportement résulte-t-il de la non-triée des données, comme avec la fonction Unix uniq?

23
demandé sur Iterator 2011-09-27 02:52:05

2 réponses

Avant les données.table V1. 9. 8, le comportement par défaut de la méthode unique.data.table était d'utiliser les clés afin de déterminer les colonnes par lesquelles les combinaisons uniques doivent être retournées. Si key était NULL (par défaut), on récupérerait les données d'origine (comme dans la situation OPs).

À partir des données.table 1.9.8+, la méthode unique.data.table utilise toutes les colonnes par défaut, ce qui est cohérent avec le unique.data.frame dans la base R. Pour qu'il utilise les colonnes clés, passez explicitement by = key(DT) dans unique (en remplaçant DT dans le appel à clé avec le nom des données.table).

Donc, l'ancien comportement serait quelque chose comme

library(data.table) v1.9.7-
set.seed(123)
a <- as.data.frame(matrix(sample(2, 120, replace = TRUE), ncol = 3))
b <- data.table(a, key = names(a))
## key(b)
## [1] "V1" "V2" "V3"
dim(unique(b)) 
## [1] 8 3

Alors que pour les données.tableau v1. 9. 8+, juste

b <- data.table(a) 
dim(unique(b)) 
## [1] 8 3
## or dim(unique(b, by = key(b)) # in case you have keys you want to use them

Ou sans copie

setDT(a)
dim(unique(a))
## [1] 8 3
23
répondu David Arenburg 2018-06-17 11:01:22

Comme mentionné par Seth les données.le paquet de table a évolué et propose maintenant des fonctions optimisées pour cela.

Pour tous ceux qui ne veulent pas entrer dans la documentation, voici le moyen le plus rapide et le plus efficace de faire ce que vous voulez:

uniqueN(a)

Et si vous voulez seulement choisir un sous-ensemble de colonnes, vous pouvez utiliser l'argument' by':

uniqueN(a,by = c('V1','V2'))

EDIT: comme mentionné dans les commentaires, cela ne donnera que le nombre de lignes uniques. Pour obtenir les valeurs uniques, Utilisez unique à la place:

unique(a)

Et pour un sous-ensemble :

unique(a[c('V1',"V2")], by=c('V1','V2'))

6
répondu Sacha 2018-06-17 12:41:42