Travailler dans R Ma table actuelle ressemble à:
C1 C2 C3 C4 1 2011-02-01 04:30:00 4 2011-02-01 04:30:00 2 2011-02-01 04:30:00 4 2011-02-01 04:35:00 3 2011-02-01 04:30:00 4 2011-02-01 04:40:00 4 2011-02-01 04:45:00 3 2011-02-01 04:45:00 5 2011-02-01 04:45:00 3 2011-02-01 04:50:00 6 2011-02-01 04:45:00 3 2011-02-01 04:55:00 7 2011-02-01 05:00:00 5 2011-02-01 05:00:00 8 2011-02-01 05:00:00 5 2011-02-01 05:05:00
Je souhaite qu'elle ressemble à ceci:
C1 C2 C3 1 2011-02-01 04:30:00 4 2 2011-02-01 04:45:00 3 3 2011-02-01 05:00:00 5 4 2011-02-01 05:15:00 6
etc. etc. veulent simplement créer une autre colonne qui monte par intervalles de cinq minutes mais qui correspond aux intervalles de C2. Je pensais à quelque chose comme la fonction rep () mais cela signifierait que les intervalles de C2 sont toujours cohérents, ce qu'ils pourraient ne pas être. Je recherche vraiment quelque chose qui fera les intervalles de cinq minutes en fonction des intervalles de C2.
Toute aide ou commentaire sur la question serait grandement apprécié. merci
4 Réponses :
Nous pouvons utiliser map2 pour créer une colonne list en prenant la seq uence de Datetime converti 'C2 'avec longueur spécifiée par l'élément correspondant de' C3 ' par intervalles de 5 minutes et unnest la colonne list XXX
Ou en utilisant Map de base R , obtenez une liste de séquences de DateTime avec le même logique que ci-dessus. Développez l'ensemble de données d'origine en rep licenciant la séquence de lignes en fonction des longueurs de 'lst1' et créez la nouvelle colonne 'C4'
df1 <- structure(list(C1 = 1:4, C2 = c("2011-02-01 04:30:00", "2011-02-01 04:45:00",
"2011-02-01 05:00:00", "2011-02-01 05:15:00"), C3 = c(4L, 3L,
5L, 6L)), class = "data.frame", row.names = c(NA, -4L))
Si la condition est basée sur la valeur suivante de 'C2'
library(data.table)
setDT(df1)[, C2 := as.POSIXct(C2)][, C4 := list(Map(seq,
MoreArgs = list(by = '5 min'), C2, shift(C2, type = 'lead',
fill = last(C2))))][, unnest(.SD)][, .SD[-1], by = C1]
Ou une option similaire utilisant des méthodes de data.table
df1 %>%
mutate(C4 = map2(ymd_hms(C2), lubridate::ymd_hms(lead(C2, default = last(C2))),
seq, by = '5 min')) %>%
unnest %>%
group_by(C1) %>%
slice(-1)
# A tibble: 9 x 4
# Groups: C1 [3]
# C1 C2 C3 C4
# <int> <chr> <int> <dttm>
#1 1 2011-02-01 04:30:00 4 2011-02-01 04:35:00
#2 1 2011-02-01 04:30:00 4 2011-02-01 04:40:00
#3 1 2011-02-01 04:30:00 4 2011-02-01 04:45:00
#4 2 2011-02-01 04:45:00 3 2011-02-01 04:50:00
#5 2 2011-02-01 04:45:00 3 2011-02-01 04:55:00
#6 2 2011-02-01 04:45:00 3 2011-02-01 05:00:00
#7 3 2011-02-01 05:00:00 5 2011-02-01 05:05:00
#8 3 2011-02-01 05:00:00 5 2011-02-01 05:10:00
#9 3 2011-02-01 05:00:00 5 2011-02-01 05:15:00
lst1 <- Map(function(x, y) seq(x, length.out = y, by = '5 min'),
as.POSIXct(df1$C2), df1$C3)
df2 <- df1[rep(seq_len(nrow(df1)), lengths(lst1)),]
df2$C4 <- do.call(c, lst1)
row.names(df2) <- NULL
Merci de votre aide! La première méthode a très bien fonctionné, mais la deuxième méthode est plus proche de ce que je recherche. Cependant, je continue à recevoir cette erreur: Erreur dans mutate_impl (.data, points): Erreur d'évaluation: erreur de connexion "par" argument. Je ne peux vraiment pas comprendre ce qui cause l'erreur, alors j'ai pensé que vous pourriez avoir une idée?
@mathsnerd Cela aurait dû fonctionner. Peut-être un problème dans la version du package. Essayez ~ seq (.x, .y, by = '5 min')
Nous pouvons créer une séquence d'intervalles de 5 min entre les valeurs min et max de C2 puis faire left_join code > sur df et remplissez les valeurs manquantes avec la valeur précédente en utilisant na.locf du zoo. library(dplyr)
library(zoo)
data.frame(C4 = seq(min(df$C2), max(df$C2), by = "5 min")) %>%
left_join(transform(df, C4 = C2)) %>%
na.locf()
# C4 C1 C2 C3
#1 2011-02-01 04:30:00 1 2011-02-01 04:30:00 4
#2 2011-02-01 04:35:00 1 2011-02-01 04:30:00 4
#3 2011-02-01 04:40:00 1 2011-02-01 04:30:00 4
#4 2011-02-01 04:45:00 2 2011-02-01 04:45:00 3
#5 2011-02-01 04:50:00 2 2011-02-01 04:45:00 3
#6 2011-02-01 04:55:00 2 2011-02-01 04:45:00 3
#7 2011-02-01 05:00:00 3 2011-02-01 05:00:00 5
#8 2011-02-01 05:05:00 3 2011-02-01 05:00:00 5
#9 2011-02-01 05:10:00 3 2011-02-01 05:00:00 5
#10 2011-02-01 05:15:00 4 2011-02-01 05:15:00 6
Une autre option tidyverse en utilisant complete,
# A tibble: 10 x 4 C4 C1 C2 C3 <dttm> <chr> <dttm> <int> 1 2011-02-01 04:30:00 1 2011-02-01 04:30:00 4 2 2011-02-01 04:35:00 1 2011-02-01 04:30:00 4 3 2011-02-01 04:40:00 1 2011-02-01 04:30:00 4 4 2011-02-01 04:45:00 2 2011-02-01 04:45:00 3 5 2011-02-01 04:50:00 2 2011-02-01 04:45:00 3 6 2011-02-01 04:55:00 2 2011-02-01 04:45:00 3 7 2011-02-01 05:00:00 3 2011-02-01 05:00:00 5 8 2011-02-01 05:05:00 3 2011-02-01 05:00:00 5 9 2011-02-01 05:10:00 3 2011-02-01 05:00:00 5 10 2011-02-01 05:15:00 4 2011-02-01 05:15:00 6
qui donne,
library(tidyverse) df %>% mutate(C2 = as.POSIXct(C2, format = '%Y-%m-%d %H:%M:%S'), C4 = C2) %>% complete(C4 = seq(min(C2), max(C2), by = '5 min')) %>% fill(C1, C2, C3)
library(lubridate) you can use this library package. Convert df[C2] as date time either using apply() or directly assigning this to date time. once it is converted then use either df[C4] <- ymd_hms(df[C2]) + min(5) or df[C4] <- ymd_hms(df[C2]) + seconds(300)
Je pense que vous avez besoin d'une ligne de plus en fonction de l'expansion de la première ligne car `` C3 '' est 4