1
votes

Remplir les valeurs manquantes

data=data.frame("student"=c(1,1,1,1,2,2,2,2,3,3,3,3,4),
                "timeHAVE"=c(1,4,7,10,2,5,NA,11,6,NA,NA,NA,3),
                "timeWANT"=c(1,4,7,10,2,5,8,11,6,9,12,15,3))

library(dplyr);library(tidyverse)
data$timeWANTattempt=data$timeHAVE
data <- data %>% 
  group_by(student) %>% 
  fill(timeWANTattempt)+3
I have 'timeHAVE' and I want to replace missing times with the previous time +3. I show my dplyr attempt but it does not work. I seek a data.table solution. Thank you.

1 commentaires

@ Je m'excuse par pourquoi cela a-t-il été voté négativement?


3 Réponses :


3
votes

vous pouvez essayer.

data %>% 
  group_by(student) %>%
  mutate(n_na = cumsum(is.na(timeHAVE))) %>% 
  mutate(timeHAVE = ifelse(is.na(timeHAVE), timeHAVE[n_na == 0 & lead(n_na) == 1] + 3*n_na, timeHAVE))
   student timeHAVE timeWANT  n_na
     <dbl>    <dbl>    <dbl> <int>
 1       1        1        1     0
 2       1        4        4     0
 3       1        7        7     0
 4       1       10       10     0
 5       2        2        2     0
 6       2        5        5     0
 7       2        8        8     1
 8       2       11       11     1
 9       3        6        6     0
10       3        9        9     1
11       3       12       12     2
12       3       15       15     3
13       4        3        3     0

J'ai inclus le petit assistant n_na qui compte les NA dans une ligne. Ensuite, la seconde mutation multiplie le nombre de NA par trois et ajoute ceci au premier élément non NA avant NA's


4 commentaires

merci beaucoup c'est génial connaissez-vous la solution data.table? Je demande parce que les données sont si volumineuses ~ 1 Go


non car je ne suis pas un expert en data.table . Mais l'idée derrière doit être traduite 1: 1 en une solution data.table .


merci beaucoup - connaissez-vous dplyr ou une solution pour: stackoverflow.com/questions/60378425/...


un peu moins de 3 millions ce sont des données historiques sur les étudiants pour le district du trou



1
votes

Voici une approche utilisant le remplissage 'locf'

setDT(data)
data[ , by = student, timeWANT := {
  # carry previous observations forward whenever missing
  locf_fill = nafill(timeHAVE, 'locf')
  # every next NA, the amount shifted goes up by another 3
  na_shift = cumsum(idx <- is.na(timeHAVE))
  # add the shift, but only where the original data was missing
  locf_fill[idx] = locf_fill[idx] + 3*na_shift[idx]
  # return the full vector
  locf_fill
}]

Attention que cela ne fonctionnera pas si un étudiant donné peut en avoir plus d'un ensemble non consécutif de valeurs NA dans timeHAVE


0 commentaires

0
votes

Une autre option data.table sans regroupement:

data = data.frame("student"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4),
        "timeHAVE"=c(1,4,7,10,2,5,NA,11,6,NA,NA,NA,NA,3),
        "timeWANT"=c(1,4,7,10,2,5,8,11,6,9,12,15,NA,3))

sortie:

    student timeHAVE timeWANT  w
 1:       1        1        1  1
 2:       1        4        4  4
 3:       1        7        7  7
 4:       1       10       10 10
 5:       2        2        2  2
 6:       2        5        5  5
 7:       2       NA        8  8
 8:       2       11       11 11
 9:       3        6        6  6
10:       3       NA        9  9
11:       3       NA       12 12
12:       3       NA       15 15
13:       4       NA       NA NA
14:       4        3        3  3

données avec étudiant = 4 ayant NA pour la première fois HAVE:

setDT(data)[, w := fifelse(is.na(timeHAVE) & student==shift(student), 
    nafill(timeHAVE, "locf") + 3L * rowid(rleid(timeHAVE)), 
    timeHAVE)]


0 commentaires