J'ai ce vecteur d'horodatage:
c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
Je voudrais supprimer les minutes et les secondes du vecteur de caractères pour avoir juste 01/09/2019 9 et 01/09/2019 10
Quelle est la méthode la plus efficace pour ce faire?
6 Réponses :
En voici une.
datevec <- c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
format(as.POSIXct(datevec, format = "%d/%m/%Y %H:%M:%OS"), "%d/%m/%Y %H")
# Result
[1] "01/09/2019 09" "01/09/2019 09" "01/09/2019 09" "01/09/2019 10" "01/09/2019 10" "01/09/2019 10"
[7] "01/09/2019 10" "01/09/2019 10" "01/09/2019 10" "01/09/2019 10"
Quelle est votre classe de sortie souhaitée? Que diriez-vous de celui-ci:
v <- c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
strptime(v, "%m/%d/%Y %H")
Un autre:
[1] "01/09/2019 9" "01/09/2019 9" "01/09/2019 9" "01/09/2019 10" "01/09/2019 10" [6] "01/09/2019 10" "01/09/2019 10" "01/09/2019 10" "01/09/2019 10" "01/09/2019 10"
donne
dates <- c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
unlist(lapply(dates,function(x) strsplit(x,":")[[1]][1]))
Cela semble bien,
mystring <- c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
microbenchmark(one = sapply(strsplit(mystring, split=':', fixed=TRUE), `[`, 1),
two = unlist(lapply(mystring,function(x) strsplit(x,":", fixed=TRUE)[[1]][1])),
three = strptime(mystring, "%m/%d/%Y %H"),
four = unlist(strsplit(mystring, split = ":", fixed=TRUE))[c(TRUE, FALSE,FALSE)],
five = format(as.POSIXct(mystring, format = "%d/%m/%Y %H:%M:%OS"), "%d/%m/%Y %H"),
six = gsub("(.*?):.*", "\\1", mystring),
seven = str_extract(mystring, ".+(?=:.+:)"),
times = 100000)
Unit: microseconds
expr min lq mean median uq max neval
one 42.792 49.471 85.63742 52.572 57.1310 669280.96 1e+05
two 64.637 70.618 114.16364 73.252 77.6840 582466.94 1e+05
three 129.456 134.771 156.82308 136.188 139.2030 339715.94 1e+05
four 12.860 15.641 22.75699 17.254 18.5440 305703.52 1e+05
five 482.888 505.647 633.15388 512.880 552.1155 551274.28 1e+05
six 37.889 43.121 52.79030 45.567 49.1880 32954.59 1e+05
seven 53.432 59.051 88.05015 62.326 69.9320 1180361.17 1e+05
(Fait avec l'aide de ici )
Une alternative pourrait être,
sapply(strsplit(mystring, split=':', fixed=TRUE), `[`, 1)
oui. Je pense que fixed = TRUE le rend beaucoup plus rapide.
Très intéressant, en fait 4, avec fixed = TRUE est le plus rapide, a changé le benchmark pour le montrer.
En voici un autre utilisant gsub
Capturez le motif par () et \\ 1 pour faire référence au groupe capturé, besoin de ? pour rendre les regex paresseux car il y a plusieurs :.
gsub("(.*?):.*", "\\1", dates)
Vous pouvez également utiliser str_extract de stringr:
date_strings <- c("01/09/2019 9:51:03", "01/09/2019 9:51:39", "01/09/2019 9:57:04",
"01/09/2019 10:01:41", "01/09/2019 10:06:06", "01/09/2019 10:09:36",
"01/09/2019 10:11:55", "01/09/2019 10:21:15", "01/09/2019 10:21:39",
"01/09/2019 10:52:20")
str_extract(date_strings, ".+(?=:.+:)")
[1] "01/09/2019 9" "01/09/2019 9" "01/09/2019 9" "01/09/2019 10"
[5] "01/09/2019 10" "01/09/2019 10" "01/09/2019 10" "01/09/2019 10"
[9] "01/09/2019 10" "01/09/2019 10"
Réponse acceptée intéressante, quelle est votre définition de l'efficacité?
Je suis plutôt biaisé envers les packages
tidyverse:)ah je vois, je ne te blâme pas :) la prochaine fois tu devrais probablement le mettre dans la question ...