2 votes

Agrégation par une sous-chaîne de la colonne

Considérons le cadre de données suivant dans R :

  TYPE    VARIAVEL                           VALOR               

  A       OPER_RELAC_VARIAVEL1                100
  A       OPER_RELAC_VARIAVEL2                200
  A       OPER_RELAC_VARIAVEL3                300
  B       OPER_RELAC_VARIAVEL1                100
  B       OPER_RELAC_VARIAVEL2                200
  B       OPER_RELAC_VARIAVEL3                300
  A       CLI_RELAC_VARIAVEL1                 450
  A       CLI_RELAC_VARIAVEL2                 320
  A       CLI_RELAC_VARIAVEL3                 110

Je veux prendre la pertinence de chaque VALOR sur la base de la racine de VARIAVEL y TYPE . Je n'ai pas de colonne avec la Racine de la VARIAVEL mais ce serait tout ce qui se trouve avant la seconde. _ ( OPER_RELAC y CLI_RELAC dans cet échantillon).

Le résultat attendu est :

  TYPE    VARIAVEL                           VALOR           RELEVANCE    

  A       OPER_RELAC_VARIAVEL1                100            0.167
  A       OPER_RELAC_VARIAVEL2                200            0.333
  A       OPER_RELAC_VARIAVEL3                300            0.500
  B       OPER_RELAC_VARIAVEL1                100            0.167
  B       OPER_RELAC_VARIAVEL2                200            0.333
  B       OPER_RELAC_VARIAVEL3                300            0.500
  A       CLI_RELAC_VARIAVEL1                 450            0.511
  A       CLI_RELAC_VARIAVEL2                 320            0.364
  A       CLI_RELAC_VARIAVEL3                 110            0.125

Puisque, par exemple, 450 représente 51,1 % du total pour le type A et la variable racine CLI_RELAC .


J'en ai fini avec cette séquence de commandes :

1) Générer une colonne avec la variable Root en utilisant la librairie stringr

dados$VARIAVEL_MAE <- str_match(dados$VARIAVEL, "^([^_]+[_][^_]+)")[,2]

Merci à R:comment faire pour que grep retourne la correspondance, plutôt que la chaîne entière

2) Résumez dans un nouveau cadre de données les totaux agrégés par cette nouvelle colonne.

TOTAIS <- aggregate(VALOR ~ Type + VARIAVEL_MAE, data = dados, sum)
names(TOTAIS) <- c('Type', 'VARIAVEL_MAE', 'TOTAL')

3) Fusionnez ces deux cadres de données en utilisant ce qui est suggéré. aquí

dados <- merge(TOTAIS, dados, by = c('Type', 'VARIAVEL_MAE'))
dados$RELEVANCIA <- dados$VALOR / dados$TOTAL;

Y a-t-il une façon plus intelligente de le faire ou ai-je besoin de toutes ces étapes ?

Ma question est la suivante : en R, tout ce que je fais peut toujours être remplacé par quelque chose de plus rapide et de plus petit.

2voto

Frank Points 51885

Dans l'exemple de l'OP, nous pouvons diviser sur _ au lieu d'utiliser une regex :

library(data.table)
setDT(DT)

DT[, paste0("vnome", 1:3) := tstrsplit(VARIAVEL, "_")]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vnome1, vnome2)]

   TYPE             VARIAVEL VALOR vnome1 vnome2    vnome3         z
1:    A OPER_RELAC_VARIAVEL1   100   OPER  RELAC VARIAVEL1 0.1666667
2:    A OPER_RELAC_VARIAVEL2   200   OPER  RELAC VARIAVEL2 0.3333333
3:    A OPER_RELAC_VARIAVEL3   300   OPER  RELAC VARIAVEL3 0.5000000
4:    B OPER_RELAC_VARIAVEL1   100   OPER  RELAC VARIAVEL1 0.1666667
5:    B OPER_RELAC_VARIAVEL2   200   OPER  RELAC VARIAVEL2 0.3333333
6:    B OPER_RELAC_VARIAVEL3   300   OPER  RELAC VARIAVEL3 0.5000000
7:    A  CLI_RELAC_VARIAVEL1   450    CLI  RELAC VARIAVEL1 0.5113636
8:    A  CLI_RELAC_VARIAVEL2   320    CLI  RELAC VARIAVEL2 0.3636364
9:    A  CLI_RELAC_VARIAVEL3   110    CLI  RELAC VARIAVEL3 0.1250000

Dans un cas plus général, mentionné par le PO comme " tout ce qui se trouve avant la deuxième ". _ ", nous pouvons utiliser L'approche de @akrun d'un autre Q&A (en supposant que VARIAVEL ne contient pas d'espace) :

DT[, c("vroot", "vseq") := 
  tstrsplit(sub('(^[^_]+_[^_]+)_(.*)$', '\\1 \\2', VARIAVEL), ' ')]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vroot)]

   TYPE             VARIAVEL VALOR      vroot      vseq         z
1:    A OPER_RELAC_VARIAVEL1   100 OPER_RELAC VARIAVEL1 0.1666667
2:    A OPER_RELAC_VARIAVEL2   200 OPER_RELAC VARIAVEL2 0.3333333
3:    A OPER_RELAC_VARIAVEL3   300 OPER_RELAC VARIAVEL3 0.5000000
4:    B OPER_RELAC_VARIAVEL1   100 OPER_RELAC VARIAVEL1 0.1666667
5:    B OPER_RELAC_VARIAVEL2   200 OPER_RELAC VARIAVEL2 0.3333333
6:    B OPER_RELAC_VARIAVEL3   300 OPER_RELAC VARIAVEL3 0.5000000
7:    A  CLI_RELAC_VARIAVEL1   450  CLI_RELAC VARIAVEL1 0.5113636
8:    A  CLI_RELAC_VARIAVEL2   320  CLI_RELAC VARIAVEL2 0.3636364
9:    A  CLI_RELAC_VARIAVEL3   110  CLI_RELAC VARIAVEL3 0.1250000

Données :

DT = structure(list(TYPE = c("A", "A", "A", "B", "B", "B", "A", "A", 
"A"), VARIAVEL = c("OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2", 
"OPER_RELAC_VARIAVEL3", "OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2", 
"OPER_RELAC_VARIAVEL3", "CLI_RELAC_VARIAVEL1", "CLI_RELAC_VARIAVEL2", 
"CLI_RELAC_VARIAVEL3"), VALOR = c(100L, 200L, 300L, 100L, 200L, 
300L, 450L, 320L, 110L)), .Names = c("TYPE", "VARIAVEL", "VALOR"
), row.names = c(NA, -9L), class = "data.frame")

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