5
votes

Répartir un entier sur plusieurs lignes autant de fois qu'il est divisé par une constante

J'ai un dataframe

       Date      repair     
 <date>           <dbl>        
 2018-07-01        1440    
 2018-07-02        1440   
 2018-07-03        1440
 2018-07-04         100
 2018-07-05          NA

où 4420 est le temps en minutes. J'essaye d'obtenir ceci:

       Date      repair     
 <date>           <dbl>        
 2018-07-01        4420    
 2018-07-02          NA   
 2018-07-03          NA
 2018-07-04          NA
 2018-07-05          NA

Où 1440 - minutes en un jour et 100 ce qui reste. Je l'ai fait avec boucle. Cela peut-il être réalisé d'une manière plus élégante?


4 commentaires

Il peut y avoir de nombreux cas extrêmes pour cette question, mais pour commencer, pouvez-vous clarifier 1) Quel serait votre résultat lorsque repair = c (4420, NA, NA, 4420, NA) ? 2) Sortie pour repair = c (4420, 100, NA, 4420, NA) . Les deux entrées ci-dessus sont-elles possibles ou ne se produiront-elles jamais?


Ils ne se produiront jamais. Le chevauchement est impossible.


Je suis désolé. Ce scénario repair = c (4420, 100, NA, 4420, NA) est possible.


@DmytroFedoriuk Je ferais peut-être mieux de poser une nouvelle question alors.


3 Réponses :


2
votes

Vous pourriez écrire une petite fonction pour cette tâche

f(x, y, length_out = 10)
# [1] 1440 1440 1440  100   NA   NA   NA   NA   NA   NA

Entrée

x <- 4420
y <- 24 * 60

Résultat

f <- function(x, y, length_out) {
  remainder <- x %% y 
  if(remainder == 0) {
    `length<-`(rep(y, x %/% y), length_out)
  } else {
    `length<-`(c(rep(y, x %/% y), remainder), length_out)
  }
}


0 commentaires

2
votes

Avec dplyr :

        Date repair
1 2018-07-01   1440
2 2018-07-02   1440
3 2018-07-03   1440
4 2018-07-04    100
5 2018-07-05     NA

Output:

library(dplyr)

df %>%
  mutate(
    repair = c(rep(1440, floor(repair[1] / 1440)), 
               repair[1] %% 1440, 
               rep(NA, n() - length(c(rep(1440, floor(repair[1] / 1440)), repair[1] %% 1440))))
  )


2 commentaires

C'est une excellente solution! Mais si le premier nombre de df est le multiple de 1440, tel que 4320, votre sortie sera 1440 1440 1440 0 NA , et non 1440 1440 1440 NA NA .


Merci, vous avez tout à fait raison; Cependant, je ne suis pas sûr de ce que OP veut dans ce cas, et d'après ce que je peux voir, il y a des exigences supplémentaires à la question (pour lesquelles je pense qu'une élaboration supplémentaire est nécessaire).



2
votes

Une solution récursive :

fun <- function(x, y, i = 0){
  if(x <= y) c(rep(y, i), x) else fun(x-y, y, i+1)
}

fun(4420, 1440)[1:nrow(df)]
# [1] 1440 1440 1440  100   NA


0 commentaires