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.
3 Réponses :
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
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
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
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)]
@ Je m'excuse par pourquoi cela a-t-il été voté négativement?