web-dev-qa-db-fra.com

Appliquer group_by et résumer sur les données tout en conservant les informations de toutes les colonnes

J'ai un grand ensemble de données avec 22 000 lignes et 25 colonnes. J'essaie de regrouper mon ensemble de données en fonction de l'une des colonnes et de prendre la valeur minimale de l'autre colonne en fonction de l'ensemble de données groupé. Cependant, le problème est que cela ne me donne que deux colonnes contenant la colonne groupée et la colonne ayant la valeur minimale ... mais j'ai besoin de toutes les informations des autres colonnes relatives aux lignes contenant les valeurs minimales. Voici un exemple simple pour le rendre reproductible:

    data<- data.frame(a=1:10, b=c("a","a","a","b","b","c","c","d","d","d"), c=c(1.2, 2.2, 2.4, 1.7, 2.7, 3.1, 3.2, 4.2, 3.3, 2.2), d= c("small", "med", "larg", "larg", "larg", "med", "small", "small", "small", "med"))

    d<- data %>%
    group_by(b) %>%
    summarise(min_values= min(c))
    d
    b min_values
    1 a        1.2
    2 b        1.7
    3 c        3.1
    4 d        2.2

Donc, il me faut aussi les informations relatives aux colonnes a et d, cependant, comme j'ai des doublons dans les valeurs de la colonne c, je ne peux pas les fusionner en fonction de la colonne min_value ... Je me demandais s'il y avait moyen de garder informations sur les autres colonnes lorsque nous utilisons le package dplyr.

J'ai trouvé quelques explications ici " dplyr: group_by, subset and summary " et ici " recherche du pourcentage dans un sous-groupe utilisant group_by et resume " mais aucune des adresses ne problème.

45

Voici deux options utilisant a) filter et b) slice de dplyr. Dans ce cas, il n'y a pas de valeurs minimales dupliquées dans la colonne c pour aucun des groupes et les résultats de a) et b) sont donc identiques. S'il y avait minima dupliqués, l'approche a) renverrait chaque minima par groupe alors que b) ne renverrait qu'un minimum (le premier) dans chaque groupe.

a)

> data %>% group_by(b) %>% filter(c == min(c))
#Source: local data frame [4 x 4]
#Groups: b
#
#   a b   c     d
#1  1 a 1.2 small
#2  4 b 1.7  larg
#3  6 c 3.1   med
#4 10 d 2.2   med

Ou similaire

> data %>% group_by(b) %>% filter(min_rank(c) == 1L)
#Source: local data frame [4 x 4]
#Groups: b
#
#   a b   c     d
#1  1 a 1.2 small
#2  4 b 1.7  larg
#3  6 c 3.1   med
#4 10 d 2.2   med

b)

> data %>% group_by(b) %>% slice(which.min(c))
#Source: local data frame [4 x 4]
#Groups: b
#
#   a b   c     d
#1  1 a 1.2 small
#2  4 b 1.7  larg
#3  6 c 3.1   med
#4 10 d 2.2   med
39

Vous pouvez utiliser group_by sans summarize:

data %>%
  group_by(b) %>%
  mutate(min_values = min(c)) %>%
  ungroup()
34
bergant

Utiliser sqldf:

library(sqldf)
 # Two options:
sqldf('SELECT * FROM data GROUP BY b HAVING min(c)')
sqldf('SELECT a, b, min(c) min, d FROM data GROUP BY b')

Sortie:

   a b   c     d
1  1 a 1.2 small
2  4 b 1.7  larg
3  6 c 3.1   med
4 10 d 2.2   med
2
mpalanco