1
votes

Créer un mannequin pour chaque heure de la journée

Je suis surpris de ne pas trouver de question sur ce site Web qui répondrait à la mienne.

Je souhaite créer 24 variables factices pour chaque heure de la journée (la valeur est 1 si l'heure est cette heure du jour et 0 dans le cas contraire). Une (très) petite partie des données ressemble à ceci:

           19 20 21
        1:  1  0  0
        2:  1  0  0
        3:  0  1  0
        4:  0  0  1

Je veux que la sortie soit comme ceci:

       df <- as.POSIXct(c("08-01-2018 19:46", "08-01-2018 19:50", "08-01- 
       2018 20:46", "09-01-2018 21:17"), format = "%d-%m-%Y %H:%M")

       [1] "2018-01-08 19:46:00 CET" "2018-01-08 19:50:00 CET" "2018-01-08 
       20:46:00 CET" "2018-01-09 21:17:00 CET"

J'ai déjà regardé cette question: Création d'un variable factice pour certaines heures de la journée

Le seul problème que j'ai avec la réponse à mon problème est que je dois écrire 24 instructions ifelse pour chaque cas.

Je me demandais s'il existe un moyen plus élégant d'obtenir cette sortie sans avoir à écrire 24 instructions ifelse.

Si cette question est un double, merci de me le faire savoir! p>

Merci d'avance,

RC

r

0 commentaires

4 Réponses :


3
votes

Est-ce que ça va? Vous pouvez utiliser as.data.frame sur la sortie si vous en avez besoin comme data.frame

library(lubridate)
hours <- as.factor(lubridate::hour(df))

# with intercept
model.matrix(~hours)

# without intercept - (+0)
model.matrix(~hours+0)

lecture supplémentaire: p>

Générer une variable factice

https://stats.stackexchange.com / questions / 174976 / pourquoi-la-colonne-d'interception-dans-la-matrice-de-modèle-remplace-le-premier-facteur


2 commentaires

S'il est possible que toutes les heures ne soient pas représentées, mais que vous souhaitez garantir les 24 variables factices, ajoutez , levels = 0: 23 à l'appel à factor .


Merci @Jonny Phelps, cela fonctionne comme un charme. Merci également à Greg Snow pour cet excellent ajout!



1
votes

Utilisation de tidyverse (édition avec suppression NA):

df <- tibble::tibble(time = as.POSIXct(c("08-01-2018 19:46", "08-01-2018 19:50", "08-01-2018 20:46", "09-01-2018 21:17"), format = "%d-%m-%Y %H:%M")
)

suppressPackageStartupMessages(library(dplyr))
df_dummy <- df %>% 
        mutate(
                hours = lubridate::hour(time),
                dummy = 1)

tidyr::pivot_wider(data = df_dummy, names_from = hours, values_from = dummy, values_fill = list(dummy = 0))
#> # A tibble: 4 x 4
#>   time                 `19`  `20`  `21`
#>   <dttm>              <dbl> <dbl> <dbl>
#> 1 2018-01-08 19:46:00     1     0     0
#> 2 2018-01-08 19:50:00     1     0     0
#> 3 2018-01-08 20:46:00     0     1     0
#> 4 2018-01-09 21:17:00     0     0     1


0 commentaires

1
votes

Ce problème peut être résolu en utilisant le package lubridate.

Solution utilisant une boucle for

hour () code> nous donne l'heure d'un objet POSIXct . En créant un vecteur des heures d'intérêt et en les laissant courir sur les points dans le temps que vous avez fournis, on peut faire ce qui suit:

df <- as.POSIXct(c("08-01-2018 19:46", "08-01-2018 19:50", "08-01-2018 20:46", "09-01-2018 21:17"), format = "%d-%m-%Y %H:%M")

Résultat

df1 <- as.data.frame(do.call(rbind,list))

  V1 V2 V3
1  1  0  0
2  1  0  0
3  0  1  0
4  0  0  1

# hours, storage vector and list for building the dataframe
hourv <- c(19:21)
storage <- c()
list <- list()
# the loop over the desired hours and points in time 
for(k in 1:4){
for(i in 1:3){
  if(hourv[i] == hour(df[k])){
    storage[i] <- 1
  }
  else{
    storage[i] <- 0
  }
}
list[[k]] <- storage
}


0 commentaires

2
votes

en utilisant la base R, vous pourriez faire:

model.matrix(~a-1,data.frame(a=factor(as.POSIXlt(df)$h)))

 a19 a20 a21
1   1   0   0
2   1   0   0
3   0   1   0
4   0   0   1
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$a
[1] "contr.treatment"


0 commentaires