2017-08-27 1 views
1

J'ai deux bases de données, qui sont basées sur un troisième ensemble de données plus grand. Je veux normaliser les données dans une base de données en fonction des entrées dans la deuxième base de données - Mon préféré serait d'utiliser dplyr, mais d'autres paquets/solutions sont très appréciés aussi :)Comment utiliser dplyr pour muter des colonnes sur des conditions à partir de deux données

Dans mon premier dataframe, j'ai le comptes de différents organes.

dataframe organ_count

# A tibble: 5 x 2 
         organs count 
         <fctr> <int> 
1      Organ_A 23 
2      Organ_B 29 
3      Organ_C 24 
4      Organ_D 145 
5      Organ_E 97 

Dans mon deuxième dataframe, je le compte des mêmes organes, mais sur dans lequel fente état où ils apparaissent dans le grand ensemble de données que j'utilisé comme source.

dataframe organ_state_count

# A tibble: 15 x 3 
       organs hmm_state count 
      <fctr>  <chr> <int> 
1  Organ_A   E1  12 
2  Organ_A   E2  2 
3  Organ_A   E3  9 
4  Organ_B   E1  13 
5  Organ_B   E2  10 
6  Organ_B   E3  6 
7  Organ_C   E1  7 
8  Organ_C   E2  7 
9  Organ_C   E3  10 
10  Organ_D   E1  72 
11  Organ_D   E2  23 
12  Organ_D   E3  50 
13  Organ_E   E1  90 
14  Organ_E   E2  2 
15  Organ_E   E3  5 

Ce que je veux faire est maintenant:

Je veux diviser le nombre organ_state_count de $ par le nombre total d'inscriptions pour cet organe (donné organ_state), ce qui dans le pourcentage de cet organe pour l'état donné.

Je l'ai déjà essayé quelque chose comme ceci:

organ_state_count %>% 
    rowwise() %>% 
    do(organ_total = filter(organ_count,organs == .$organs)) %>% 
    mutate(organ_norm=.$count/organ_total) 

Mais il jette ce message d'erreur:

Error in mutate_impl(.data, dots) : 
Evaluation error: arguments imply differing number of rows: 1, 0. 
In addition: Warning messages: 
1: Unknown or uninitialised column: 'count'. 
2: In Ops.factor(left, right) : ‘/’ not meaningful for factors 

je dois admettre que je suis assez nouveau à R et à l'ensemble dplyr/chose tidyverse aussi, donc je suis un peu débordé.

Je pense aussi qu'il y a une sorte de possibilité d'utiliser simplement le cadre organ_state_count pour cette tâche, et de tout résoudre dans une seule base de données, mais je ne sais pas comment.

Merci pour vos réponses et votre aide!

+1

dans la base R, avec 'ave':' dat perc $ <- dat $ count/ave (dat $ count, dat organes $, FUN = somme) 'où dat est le nom de votre deuxième data.frame. – lmo

+0

a également travaillé très bien pour moi, je voulais juste rester dans le paquet dplyr plus, alors j'ai accepté l'autre réponse :) Néanmoins, merci pour votre aide! – jakoberr

Répondre

2

vous pouvez essayer quelque chose comme:

df %>% 
    group_by(organs) %>% 
    mutate(tot = sum(count)) %>% 
    ungroup() %>% 
    mutate(pct = count/tot) 

Il n'y a pas besoin d'utiliser la première trame de données, que vous avez cette information dans la seconde trame de données déjà. Sélectionnez simplement les colonnes que vous souhaitez utiliser pour la sortie finale.

données:

df <- read.table(text = "id organs hmm_state count 
1 Organ_A E1 12 
2 Organ_A E2 2 
3 Organ_A E3 9 
4 Organ_B E1 13 
5 Organ_B E2 10 
6 Organ_B E3 6 
7 Organ_C E1 7 
8 Organ_C E2 7 
9 Organ_C E3 10 
10 Organ_D E1 72 
11 Organ_D E2 23 
12 Organ_D E3 50 
13 Organ_E E1 90 
14 Organ_E E2 2 
15 Organ_E E3 5", sep =" ", header = TRUE) 

sortie:

 id organs hmm_state count tot  pct 
    <int> <fctr> <fctr> <int> <int>  <dbl> 
1  1 Organ_A  E1 12 23 0.52173913 
2  2 Organ_A  E2  2 23 0.08695652 
3  3 Organ_A  E3  9 23 0.39130435 
4  4 Organ_B  E1 13 29 0.44827586 
5  5 Organ_B  E2 10 29 0.34482759 
6  6 Organ_B  E3  6 29 0.20689655 
7  7 Organ_C  E1  7 24 0.29166667 
8  8 Organ_C  E2  7 24 0.29166667 
9  9 Organ_C  E3 10 24 0.41666667 
10 10 Organ_D  E1 72 145 0.49655172 
11 11 Organ_D  E2 23 145 0.15862069 
12 12 Organ_D  E3 50 145 0.34482759 
13 13 Organ_E  E1 90 97 0.92783505 
14 14 Organ_E  E2  2 97 0.02061856 
15 15 Organ_E  E3  5 97 0.05154639 
+0

A travaillé comme un charme, merci beaucoup! – jakoberr