Как я могу преобразовать определенное время в - PullRequest
0 голосов
/ 25 октября 2019

Я хочу преобразовать строковый столбец в правильный формат.

Обычно я делал бы что-то вроде:

print(df$Time) 
> "00:00:01"
as.POSIXct(df$Time,format="%H:%M:%S")

Однако мои данные странные. Это выглядит так:

print(df$Time)
850a"  "823a"  NA      "906a"  "321a"  "1154p"

Мое решение не работает. Так как я сначала раздели символы (в данном случае «а» и «р»). Но после этого мне не хватает важной части (если это утро или день).

Поэтому мой вопрос: как я могу преобразовать эти данные в правильный формат?

Ожидаемый результат:

df$Time_Old
850a"  "823a"  NA      "906a"  "321a"  "1154p"

df$Time_New
08.50   08.23    NA    09.06   03.21   23.54

Некоторый примерданные:

vector_string <- as.vector(tv_Adds[["Time"]])
vector_string = vector_string[1:20]
> vector_string 


[1] "850a"  "823a"  NA      "906a"  "321a"  "1154p" "608p"  "1012a" "354a"  "1121p" "414p"  "1241p" "721p"  "223p"  "316p" 
[16] "345p"  "1145a" "3p"    "937a"  "138p"

> dput(vector_string[1:20])
c("850a", "823a", NA, "906a", "321a", "1154p", "608p", "1012a", 
"354a", "1121p", "414p", "1241p", "721p", "223p", "316p", "345p", 
"1145a", "3p", "937a", "138p")

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Вы должны отделить часы от минут, так как ввод, как вы даете, является неоднозначным. Затем добавьте «m» в конце не-NA записей. Я думаю, что вам нужно это:

tvec = c("850a",  "823a",  NA, "906a",  "321a",  "1154p")
notNA <- !is.na(tvec)

#separate hours from minutes with a dot and append m at the end:
tvec[notNA] <- paste0(strtrim(tvec[notNA], nchar(tvec[notNA]) - 3), ".", 
                      substr(tvec[notNA], nchar(tvec[notNA])-2, nchar(tvec[notNA]))
, "m")

as.POSIXct(tvec, format = "%I.%M%p")
[1] "2019-10-25 08:50:00 CEST" "2019-10-25 08:23:00 CEST"
[3] NA                         "2019-10-25 09:06:00 CEST"
[5] "2019-10-25 03:21:00 CEST" "2019-10-25 23:54:00 CEST"

"%I.%M%p" означает

hour(0-12), followed by .,followed by minutes(00-59), followed by "am"(or "pm")

1 голос
/ 29 октября 2019

Исходя из вашего общего примера, кажется, что у вас есть 3 различных случая, которые нам нужно обработать.

  1. Когда у вас есть 834a, который должен стать 8:34am
  2. Когда у вас есть 1143p, который должен стать 11:43pm
  3. Когда у вас есть 3a, который должен стать 3:00am

После того, как они обработаны, в этом случае спростой оператор ifelse, подсчитывающий количество символов и изменяющий соответствующим образом, затем мы можем одновременно преобразовать объект datetime, вызвав strptime с правильным форматом, т.е.

v1[!is.na(v1)] <- paste0(v1[!is.na(v1)], 'm')
v2 <- ifelse(nchar(v1) == 5, gsub('(^[0-9]{1})(.*$)', '\\1:\\2', v1), 
           ifelse(nchar(v1) == 3, gsub('(^[0-9]{1})(.*$)', '\\1:00\\2', v1), 
                                                  gsub('(^[0-9]{2})(.*$)', '\\1:\\2', v1)))

v2
#[1] "8:50am"  "8:23am"  NA        "9:06am"  "3:21am"  "11:54pm" "6:08pm"  "10:12am" "3:54am"  "11:21pm" "4:14pm"  "12:41pm" "7:21pm"  "2:23pm"  "3:16pm"  "3:45pm"  "11:45am" "3:00pm"  "9:37am"  "1:38pm" 

strptime(v2, format = '%I:%M%p')
#[1] "2019-10-29 08:50:00 +03" "2019-10-29 08:23:00 +03" NA                        "2019-10-29 09:06:00 +03" "2019-10-29 03:21:00 +03" "2019-10-29 23:54:00 +03" "2019-10-29 18:08:00 +03" "2019-10-29 10:12:00 +03" "2019-10-29 03:54:00 +03" "2019-10-29 23:21:00 +03"
#[11] "2019-10-29 16:14:00 +03" "2019-10-29 12:41:00 +03" "2019-10-29 19:21:00 +03" "2019-10-29 14:23:00 +03" "2019-10-29 15:16:00 +03" "2019-10-29 15:45:00 +03" "2019-10-29 11:45:00 +03" "2019-10-29 15:00:00 +03" "2019-10-29 09:37:00 +03" "2019-10-29 13:38:00 +03"

DATA USED

dput(v1)
c("850am", "823am", NA, "906am", "321am", "1154pm", "608pm", 
"1012am", "354am", "1121pm", "414pm", "1241pm", "721pm", "223pm", 
"316pm", "345pm", "1145am", "3pm", "937am", "138pm")
...