J'ai regardé un certain nombre de fils et je ne trouve pas tout à fait ce que je recherche. J'ai un ensemble de données avec plusieurs identifiants et dates comme ci-dessous.
df %>% group_by(id, date) %>% arrange(code)
Je ne veux pas de dates en double par identifiant et je souhaite le sélectionner en fonction de la valeur de code la plus basse pour que cela se termine comme suit:
id date code 1 2000-10-08 35 1 2001-01-01 70 1 2008-09-05 5 2 2006-02-01 188 3 2010-10-10 25
J'ai utilisé la fonction group_by pour qu'elle traite les données par identifiant et date:
id date code 1 2000-10-08 690 1 2000-10-08 75 1 2000-10-08 35 1 2001-01-01 315 1 2001-01-01 70 1 2008-09-05 690 1 2008-09-05 5 1 2008-09-05 60 2 2006-02-01 188 2 2006-02-01 198 2 2006-02-01 555 2 2006-02-01 690 3 2010-10-10 120 3 2010-10-10 75 3 2010-10-10 25
Cependant, j'ai du mal à déterminer quel code utiliser pour pour ne conserver que la valeur la plus basse de chaque combinaison id / date.
Quelqu'un pourrait-il m'aider?
Merci
4 Réponses :
data.table
approche
dt <- fread("id date code 1 2000-10-08 690 1 2000-10-08 75 1 2000-10-08 35 1 2001-01-01 315 1 2001-01-01 70 1 2008-09-05 690 1 2008-09-05 5 1 2008-09-05 60 2 2006-02-01 188 2 2006-02-01 198 2 2006-02-01 555 2 2006-02-01 690 3 2010-10-10 120 3 2010-10-10 75 3 2010-10-10 25", header = TRUE)
exemple de données
library( data.table ) dt[, .( min = min( code ) ), by = .( id, date )] # id date min # 1: 1 2000-10-08 35 # 2: 1 2001-01-01 70 # 3: 1 2008-09-05 5 # 4: 2 2006-02-01 188 # 5: 3 2010-10-10 25
Avec tidyverse
, vous pouvez faire:
library(tidyverse) dt %>% group_by(id, date) %>% summarise(code = min(code)) id date x 1 1 2000-10-08 35 2 1 2001-01-01 70 3 1 2008-09-05 5 4 2 2006-02-01 188 5 3 2010-10-10 25
Du point de vue tidyverse
, s'il y a beaucoup de colonnes et que la ligne est nécessaire en fonction de la valeur imum min
de 'code' pour chaque groupe, il peut être filtre
avec une condition logique
df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L), date = c("2000-10-08", "2000-10-08", "2000-10-08", "2001-01-01", "2001-01-01", "2008-09-05", "2008-09-05", "2008-09-05", "2006-02-01", "2006-02-01", "2006-02-01", "2006-02-01", "2010-10-10", "2010-10-10", "2010-10-10"), code = c(690L, 75L, 35L, 315L, 70L, 690L, 5L, 60L, 188L, 198L, 555L, 690L, 120L, 75L, 25L)), class = "data.frame", row.names = c(NA, -15L))
S'il y a des liens pour la valeur min
pour chaque groupe et que vous ne voulez que la première occurrence du min
'code'
aggregate(code ~ id + date, df, min) # id date code #1 1 2000-10-08 35 #2 1 2001-01-01 70 #3 2 2006-02-01 188 #4 1 2008-09-05 5 #5 3 2010-10-10 25
Ou une autre option utilise top_n
df %>% group_by(id, date) %>% top_n(1, -code)
Utilisation de l ' agrégat
de la base R
df %>% group_by(id, date) %>% slice(which.min(code))
library(tidyverse) df %>% group_by(id, date) %>% filter(code == min(code)) # A tibble: 5 x 3 # Groups: id, date [5] # id date code # <int> <chr> <int> #1 1 2000-10-08 35 #2 1 2001-01-01 70 #3 1 2008-09-05 5 #4 2 2006-02-01 188 #5 3 2010-10-10 25
Ajoutez simplement slice (1)
à la fin de votre code:
df %>% group_by(id, date) %>% arrange(code) %>% slice(1) ## # A tibble: 5 x 3 ## # Groups: id, date [5] ## id date code ## <int> <fct> <int> ## 1 1 2000-10-08 35 ## 2 1 2001-01-01 70 ## 3 1 2008-09-05 5 ## 4 2 2006-02-01 188 ## 5 3 2010-10-10 25
utilisez
min
, cela fonctionne pour chaque groupe ...De plus, vous aurez besoin de
summary
au lieu dearrange
.La question n'est pas une dupe de stackoverflow.com/questions/9723208/... parce que l'agrégation n'est qu'un moyen (peut-être pas le meilleur) de répondre à la question.
@Ista D'accord. Qu'en est-il de stackoverflow.com/questions/24070714/...