1
votes

Réplication des valeurs dans R par groupe

J'ai un ensemble de données contenant une mesure et le jour précis où elle a été collectée. Je voudrais reproduire les valeurs entre les jours, jusqu'au dernier jour de mesure. Par exemple, voici les données avant leur réplication:

           Measurement    Day
Subject1   .86            1
Subject1   .86            2
Subject1   .86            3
Subject1   .86            4
Subject1   .86            5 
Subject1   .86            6           
Subject1   .91            7
Subject1   .91            8            
Subject1   .83            9            
Subject2   .77            0
Subject2   .77            1
Subject2   .77            2
Subject2   .77            3
Subject2   .77            4       
Subject2   .82            5          
Subject2   .82            6
Subject2   .82            7     
Subject2   .82            8     
Subject2   .82            9     
Subject2   .82            10
Subject2   .82            11                      
Subject2   .86            12    

Je voudrais modifier l'ensemble de données ci-dessus dans R pour qu'il ressemble à ce qui suit:

           Measurement    Day
Subject1   .86            1            
Subject1   .91            7            
Subject1   .83            9            
Subject2   .77            0            
Subject2   .82            5            
Subject2   .86            12    


0 commentaires

3 Réponses :


4
votes

Nous pouvons utiliser complete . En supposant que les données d'entrée de l'OP sont de la matrice (car data.frame n'autorise pas les noms de lignes en double et en supposant qu'il y a row.names - wow beaucoup d'hypothèses), créez un data.frame avec as.data.frame tandis que cbind insère le row.names sous forme de colonne, groupé par 'Subject', utilisez complete pour obtenir la séquence complète de "Jour", puis remplir les NA dans "Mesure" avec la valeur précédente non-NA

dat <- structure(c(0.86, 0.91, 0.83, 0.77, 0.82, 0.86, 1, 7, 9, 0, 5, 
12), .Dim = c(6L, 2L), .Dimnames = list(c("Subject1", "Subject1", 
"Subject1", "Subject2", "Subject2", "Subject2"), c("Measurement", 
"Day")))

data

library(tidyverse)    
cbind(Subject = row.names(dat), as.data.frame(dat)) %>%
   group_by(Subject) %>%
   complete(Day = first(Day):last(Day)) %>%
   fill(Measurement) %>%
   select(Subject, Measurement, Day)
# A tibble: 22 x 3
# Groups:   Subject [2]
#   Subject  Measurement   Day
#   <fct>          <dbl> <dbl>
# 1 Subject1        0.86     1
# 2 Subject1        0.86     2
# 3 Subject1        0.86     3
# 4 Subject1        0.86     4
# 5 Subject1        0.86     5
# 6 Subject1        0.86     6
# 7 Subject1        0.91     7
# 8 Subject1        0.91     8
# 9 Subject1        0.83     9
310 Subject2        0.77     0
# … with 12 more rows


0 commentaires

1
votes
> foo = function(x){
+     r = range(x)
+     as.numeric(seq(r[1], r[2]) %in% x)
+ }
> do.call(rbind, lapply(split(1:NROW(dat), row.names(dat)), function(i){
+     temp = dat[i,]
+     temp = temp[with(rle(cumsum(foo(temp[,"Day"]))), rep(seq_along(lengths), lengths)),]
+     temp[,"Day"] = ave(temp[, "Day"], temp[,"Day"], FUN = function(x) x + (1:length(x) - 1))
+     temp
+ }))
         Measurement Day
Subject1        0.86   1
Subject1        0.86   2
Subject1        0.86   3
Subject1        0.86   4
Subject1        0.86   5
Subject1        0.86   6
Subject1        0.91   7
Subject1        0.91   8
Subject1        0.83   9
Subject2        0.77   0
Subject2        0.77   1
Subject2        0.77   2
Subject2        0.77   3
Subject2        0.77   4
Subject2        0.82   5
Subject2        0.82   6
Subject2        0.82   7
Subject2        0.82   8
Subject2        0.82   9
Subject2        0.82  10
Subject2        0.82  11
Subject2        0.86  12

0 commentaires

1
votes

Légèrement basé sur la réponse de @akrun

 library(tidyverse)

    df <- cbind(Subject = row.names(dat), as.data.frame(dat))

    df %>% group_by(Subject) %>% 
      mutate(day_diff = c(diff(Day), 1)) %>% 
      uncount(day_diff) %>% 
      mutate(Day = first(Day):last(Day)) %>% 
      ungroup()


0 commentaires