2017-09-12 3 views
1

J'ai des données qui ont deux mesures de deux groupes différents avec un nombre d'échantillons pour chacun. Je version simple avec 6 échantillons chacun ressemble à ceci:Comment utiliser map() pour ajouter un index groupé à une colonne de blocs de données?

library(tidyverse) 

df <- tibble(group = c(rep("group_A", 12), rep("group_B", 12)), 
     sample = rep(1:6, 4), 
     measurement = rep(c(rep("meas_A", 6), rep("meas_B", 6)), 2), 
     value = round(runif(24, min = 0, max = 60))) 

mais parce que les mesures ont été répétées dans différentes conditions, il est en fait une série de trames de données similaires représentés dans une liste:

df2 <- bind_rows(df,df,df,df) %>% 
    mutate(condition = c(rep("One", 24), rep("Two", 24), 
         rep("Three", 24), rep("Four", 24))) %>% 
    unite(group_meas, group, measurement) %>% 
    nest(-condition) 

En fin de compte Je voudrais remodeler chaque trame de données dans un format large afin que les vecteurs des deux mesures pour chaque groupe puissent être facilement extraits des colonnes simples pour la comparaison statistique. Par exemple:

df %>% unite(group_meas, group, measurement) 
    %>% spread(group_meas, value) 

qui peut être mis en correspondance dans la liste comme ceci:

df2 %>% mutate(data = map(data, ~spread(.x, group_meas, value))) 

Mon problème se pose lorsqu'un échantillon a été mesuré plus d'une fois et spread() ne fonctionne pas parce qu'il ya

Duplicate identifiers for rows

Je pense que le meilleur moyen d'y parvenir est d'ajouter une nouvelle colonne d'index groupée sur le groupe/mesurés combinés ement et ceci fournira des identifiants de rangée uniques. Cela fonctionne pour un seul cadre de données.

df %>% unite(group_meas, group, measurement) %>% 
    group_by(group_meas) %>% 
    mutate(gr_m_index = row_number()) 

Cependant, je ne peux pas mettre à l'échelle pour mapper une liste.

df2 %>% mutate(data = map(data, ~ group_by(.x, group_meas) %>% 
          mutate(gr_m_index = row_number()))) 

Je pense que cela doit être une chose tidyeval que je reçois l'erreur suivante suggérant qu'elle est à la recherche dans le mauvais endroit.

Evaluation error: Column gr_m_index must be length 24 (the number of rows) or one, not 4.

Comment j'utiliser map() pour ajouter un index groupé à une colonne de trames de données? Si je comprends bien, basé sur le message d'erreur, row_number() renvoyait c(1, 2, 3, 4)

Répondre

1

Cela est dû au fait que le nombre de lignes a été compté en fonction de df2, plutôt que des trames de données imbriquées.

approche Soit ci-dessous devrait fonctionner:

Approche 1. Définissez toutes les transformations à mapper en tant que fonction autonome.

index_spread <- function(data){ 
    return(data %>% 
      group_by(group_meas) %>% 
      mutate(gr_m_index = row_number()) %>% 
      spread(group_meas, value)) 
} 

df2 %>% mutate(data = map(data, index_spread)) %>% unnest() 

# A tibble: 24 x 7 
    condition sample gr_m_index group_A_meas_A group_A_meas_B group_B_meas_A group_B_meas_B 
     <chr> <int>  <int>   <dbl>   <dbl>   <dbl>   <dbl> 
1  One  1   1    12    43    39    52 
2  One  2   2    11    60    8    20 
3  One  3   3    41    23    16    29 
4  One  4   4    23    47    23    36 
5  One  5   5    46    56    1    30 
6  One  6   6    30    13    23    11 
7  Two  1   1    12    43    39    52 
8  Two  2   2    11    60    8    20 
9  Two  3   3    41    23    16    29 
10  Two  4   4    23    47    23    36 
# ... with 14 more rows 

Approche 2. Effectuez les transformations sur df2$data, & attribuez la liste des trames de données transformées à l'original.

df2$data <- map(df2$data, ~group_by(.x, group_meas) %>% 
        mutate(gr_m_index = row_number()) %>% 
        spread(group_meas, value)) 
df2 %>% unnest() 

# (same output as above)