strptime - 在 csv 文件中设置数据格式
strptime - set format with data in csv file
示例原始数据:
1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009
我在使用 strptime 进行格式化时遇到问题,因为我有来自 csv 文件的数据。
dates <- read.csv(file = "Australia_timestamp.csv")
colnames(dates) <- c("Date")
format <- "%a %b %d %H:%M:%S %z %Y"
dates <-strptime(dates[], format = format)
输出:
NA
如何通过没有 NA
和正确格式的输出来解决这个问题?
您得到的 NA 是因为 %z 没有捕获 PDT。它属于 %Z
,因为它不是数字,但 strptime
不支持 %Z
输入,因为字符缩写不是明确的。 PDT 是 UTC-7,因此要使用 strptime
捕获时间戳,您的字符串必须是
Tue Apr 07 03:06:17 -0700 2009
解决问题的方法取决于您拥有的数据。如果您所有的时间戳都在 PDT 中,您只需将所有字符串中的 PDT 替换为 -0700:
dates$Date <- gsub("PDT", "-0700", dates$Date)
dates$Date <- strptime(dates$Date, format = format)
1) 主题引用了一个 csv 文件,但显示的数据不是 csv 格式。我们将假设问题中显示的表格是正确的,并且输入文件仅包含第一行 1,第二行描述 date/time,第三行是空白等等,如末尾的注释所示.
我们逐行读取它,然后在连续的行前面加上num:
、datetime:
和一个空字符串。这会将它转换为 debian 控制格式形式 (dcf),因此我们可以使用 read.dcf
来读取它并给出一个字符矩阵。将其转换为数据框,使用 convert.type 将第一列转换为数字并将第二列转换为 POSIXct。
下面管道中的前两行是为了利用注释中的 Lines
来重现,但要从文件中读取相同内容,只需将管道中的前两行替换为类似这样的内容, "myfile" |>
其中 myfile
是输入文件的名称。
没有使用包。
prefix <- \(x) paste(rep(c("num:", "time:", ""), length = length(x)), x)
Lines |>
textConnection(name = "") |>
readLines() |>
trimws() |>
prefix() |>
textConnection(name = "") |>
read.dcf() |>
as.data.frame() |>
type.convert(as.is = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
给这个 data.frame:
num time
1 1 2009-04-06 23:55:14
2 2 2009-04-07 01:16:43
3 3 2009-04-07 03:06:17
2) 另一种方法是将数据转换为矩阵,如图所示,然后按上述步骤进行操作。
Lines |>
textConnection(name = "") |>
read.table(sep = "?", strip.white = TRUE) |>
unlist() |>
matrix(ncol = 2, byrow = TRUE, dimnames = list(NULL, c("num", "time"))) |>
as.data.frame() |>
type.convert(as.is = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
3) 如果问题中显示的格式是错误的,这意味着 1, 2, 3, ... 出现在同一行的日期时间之前像这样然后逐行读取它,用逗号替换第一个 space 并将其读入具有指定列名的数据框中。最后将时间列转换为POSIXct。
Lines2 <- "1 Mon Apr 06 23:55:14 PDT 2009
2 Tue Apr 07 01:16:43 PDT 2009
3 Tue Apr 07 03:06:17 PDT 2009"
Lines2 |>
textConnection(name = "") |>
readLines() |>
trimws() |>
sub(pattern = " ", replacement = ",") |>
textConnection(name = "") |>
read.table(sep = ",", col.names = c("num", "time"), strip.white = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
4) 如果输入确实是一个 csv 文件但没有第 3 行中所示的列 headers 那么它就更容易了:
Lines3 <- "1,Mon Apr 06 23:55:14 PDT 2009
2,Tue Apr 07 01:16:43 PDT 2009
3,Tue Apr 07 03:06:17 PDT 2009"
Lines3 |>
textConnection(name = "") |>
read.table(sep = ",", col.names = c("num", "time"), strip.white = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
备注
Lines <- "1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009"
我们可以使用 parse_date
来自 parsedate
library(tibble)
library(parsedate)
lines1 <- lines[nzchar(lines)]
tibble(num = lines1[c(TRUE, FALSE)], time = parse_date(lines1[c(FALSE, TRUE)]))
-输出
# A tibble: 3 × 2
num time
<chr> <dttm>
1 1 2009-04-06 23:55:14
2 2 2009-04-07 01:16:43
3 3 2009-04-07 03:06:17
数据
lines <- readLines(textConnection("1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009"))
# or read from the file
lines <- readLines("file.txt")
示例原始数据:
1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009
我在使用 strptime 进行格式化时遇到问题,因为我有来自 csv 文件的数据。
dates <- read.csv(file = "Australia_timestamp.csv")
colnames(dates) <- c("Date")
format <- "%a %b %d %H:%M:%S %z %Y"
dates <-strptime(dates[], format = format)
输出:
NA
如何通过没有 NA
和正确格式的输出来解决这个问题?
您得到的 NA 是因为 %z 没有捕获 PDT。它属于 %Z
,因为它不是数字,但 strptime
不支持 %Z
输入,因为字符缩写不是明确的。 PDT 是 UTC-7,因此要使用 strptime
捕获时间戳,您的字符串必须是
Tue Apr 07 03:06:17 -0700 2009
解决问题的方法取决于您拥有的数据。如果您所有的时间戳都在 PDT 中,您只需将所有字符串中的 PDT 替换为 -0700:
dates$Date <- gsub("PDT", "-0700", dates$Date)
dates$Date <- strptime(dates$Date, format = format)
1) 主题引用了一个 csv 文件,但显示的数据不是 csv 格式。我们将假设问题中显示的表格是正确的,并且输入文件仅包含第一行 1,第二行描述 date/time,第三行是空白等等,如末尾的注释所示.
我们逐行读取它,然后在连续的行前面加上num:
、datetime:
和一个空字符串。这会将它转换为 debian 控制格式形式 (dcf),因此我们可以使用 read.dcf
来读取它并给出一个字符矩阵。将其转换为数据框,使用 convert.type 将第一列转换为数字并将第二列转换为 POSIXct。
下面管道中的前两行是为了利用注释中的 Lines
来重现,但要从文件中读取相同内容,只需将管道中的前两行替换为类似这样的内容, "myfile" |>
其中 myfile
是输入文件的名称。
没有使用包。
prefix <- \(x) paste(rep(c("num:", "time:", ""), length = length(x)), x)
Lines |>
textConnection(name = "") |>
readLines() |>
trimws() |>
prefix() |>
textConnection(name = "") |>
read.dcf() |>
as.data.frame() |>
type.convert(as.is = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
给这个 data.frame:
num time
1 1 2009-04-06 23:55:14
2 2 2009-04-07 01:16:43
3 3 2009-04-07 03:06:17
2) 另一种方法是将数据转换为矩阵,如图所示,然后按上述步骤进行操作。
Lines |>
textConnection(name = "") |>
read.table(sep = "?", strip.white = TRUE) |>
unlist() |>
matrix(ncol = 2, byrow = TRUE, dimnames = list(NULL, c("num", "time"))) |>
as.data.frame() |>
type.convert(as.is = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
3) 如果问题中显示的格式是错误的,这意味着 1, 2, 3, ... 出现在同一行的日期时间之前像这样然后逐行读取它,用逗号替换第一个 space 并将其读入具有指定列名的数据框中。最后将时间列转换为POSIXct。
Lines2 <- "1 Mon Apr 06 23:55:14 PDT 2009
2 Tue Apr 07 01:16:43 PDT 2009
3 Tue Apr 07 03:06:17 PDT 2009"
Lines2 |>
textConnection(name = "") |>
readLines() |>
trimws() |>
sub(pattern = " ", replacement = ",") |>
textConnection(name = "") |>
read.table(sep = ",", col.names = c("num", "time"), strip.white = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
4) 如果输入确实是一个 csv 文件但没有第 3 行中所示的列 headers 那么它就更容易了:
Lines3 <- "1,Mon Apr 06 23:55:14 PDT 2009
2,Tue Apr 07 01:16:43 PDT 2009
3,Tue Apr 07 03:06:17 PDT 2009"
Lines3 |>
textConnection(name = "") |>
read.table(sep = ",", col.names = c("num", "time"), strip.white = TRUE) |>
transform(time = as.POSIXct(time, format = "%a %b %d %H:%M:%S PDT %Y"))
备注
Lines <- "1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009"
我们可以使用 parse_date
来自 parsedate
library(tibble)
library(parsedate)
lines1 <- lines[nzchar(lines)]
tibble(num = lines1[c(TRUE, FALSE)], time = parse_date(lines1[c(FALSE, TRUE)]))
-输出
# A tibble: 3 × 2
num time
<chr> <dttm>
1 1 2009-04-06 23:55:14
2 2 2009-04-07 01:16:43
3 3 2009-04-07 03:06:17
数据
lines <- readLines(textConnection("1
Mon Apr 06 23:55:14 PDT 2009
2
Tue Apr 07 01:16:43 PDT 2009
3
Tue Apr 07 03:06:17 PDT 2009"))
# or read from the file
lines <- readLines("file.txt")