从长格式到宽格式的转换会产生重复的时间标识符行
Long to wide format conversion gives duplicate time identifier rows
请在投票结束前查看聊天记录
我有以下数据:
> dput(head(q,10))
structure(list(Date = structure(c(1471424400, 1471424400, 1471424400,
1471424401, 1471424401, 1471424406, 1471424407, 1471424415, 1471424417,
1471424514), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Type = c("ASK", "BID", "ASK", "BID", "ASK", "ASK", "BID",
"BID", "BID", "ASK"), Price = c(1749.95, 1611, 1683.9, 1653,
1672, 1683.9, 1653, 1654.2, 1663, 1682)), .Names = c("Date",
"Type", "Price"), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
然后我使用了下面的代码:
data.new <- group_by(head(q,10), Date, Type) %>% summarize(price=ifelse(Type[1] == 'ASK', min(Price)
然后用
dputed<-dput(ungroup(data.new))
dput(dputed)
structure(list(Date = structure(c(1471424400, 1471424400, 1471424401,
1471424401, 1471424406, 1471424407, 1471424415, 1471424417, 1471424514
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Type = c("ASK",
"BID", "ASK", "BID", "ASK", "BID", "BID", "BID", "ASK"), price = c(1683.9,
1611, 1672, 1653, 1683.9, 1653, 1654.2, 1663, 1682)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -9L), .Names = c("Date",
"Type", "price"))
我想将其转换为宽格式,其中 日期、报价和报价是三列,行包含特定时间戳的报价和报价值。
这是我试过的:
m.q<-dcast(dputed,Date ~ Type, value.var = "price")
但是结果有重复的时间戳。请注意相邻两行中的时间戳 (2016-08-17 09:00:06)。由于 bid 和 aks 不在同一行:
> dput(m.q)
structure(list(Date = structure(c(1471424400, 1471424401, 1471424406,
1471424407, 1471424415, 1471424417, 1471424514), class = c("POSIXct",
"POSIXt"), tzone = "UTC"), ASK = c(1683.9, 1672, 1683.9, NA,
NA, NA, 1682), BID = c(1611, 1653, NA, 1653, 1654.2, 1663, NA
)), .Names = c("Date", "ASK", "BID"), row.names = c(NA, -7L), class = "data.frame")
请注意,当我使用 complete.cases() 时,我只得到 2 行而不是 3 行,因为 2016-08-17 09:00:06 被删除,因为出价和要价被分成两行相同的时间戳。
johny<- m.q[complete.cases(m.q),]
> dput(johny)
structure(list(Date = structure(c(1471424400, 1471424401), class = c("POSIXct",
"POSIXt"), tzone = "UTC"), ASK = c(1683.9, 1672), BID = c(1611,
1653)), .Names = c("Date", "ASK", "BID"), row.names = 1:2, class = "data.frame")
见下方编辑:
您提供的代码没有表现出您声称的行为:
m.q
Date ASK BID
1 2016-08-17 09:00:00 1683.9 1611.0
2 2016-08-17 09:00:01 1672.0 1653.0
3 2016-08-17 09:00:06 1683.9 NA
4 2016-08-17 09:00:07 NA 1653.0
5 2016-08-17 09:00:15 NA 1654.2
6 2016-08-17 09:00:17 NA 1663.0
7 2016-08-17 09:01:54 1682.0 NA
使用查看命令:
View(m.q)
让我们只检查该列:
m.q$Date
[1] "2016-08-17 09:00:00 UTC" "2016-08-17 09:00:01 UTC" "2016-08-17 09:00:06 UTC"
[4] "2016-08-17 09:00:07 UTC" "2016-08-17 09:00:15 UTC" "2016-08-17 09:00:17 UTC"
[7] "2016-08-17 09:01:54 UTC"
还要检查重复项:
duplicated(m.q$Date)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
没有其他方式可以告诉您您提供的数据没有重复。
编辑
按住按钮!暂时不要删除。显示器有问题。收到您的原始数据后:
library(readxl)
q <- read_excel("~/Data/3_day_1_stock.xlsx", sheet=1, skip=1)
dput(head(q, 10))
# # A tibble: 10 x 3
# Date Type Price
# <time> <chr> <dbl>
# 1 2016-08-17 09:00:00 ASK 1749.95
# 2 2016-08-17 09:00:00 BID 1611.00
# 3 2016-08-17 09:00:00 ASK 1683.90
# 4 2016-08-17 09:00:01 BID 1653.00
# 5 2016-08-17 09:00:01 ASK 1672.00
# 6 2016-08-17 09:00:06 ASK 1683.90
# 7 2016-08-17 09:00:06 BID 1653.00
# 8 2016-08-17 09:00:14 BID 1654.20
# 9 2016-08-17 09:00:17 BID 1663.00
# 10 2016-08-17 09:01:54 ASK 1682.00
第 6 行和第 7 行的日期似乎重复了。但进一步检查它们是不同的:
dput(head(q, 10))
structure(list(Date = structure(c(1471424400, 1471424400, 1471424400,
1471424401, 1471424401, 1471424406, **1471424407**__, 1471424415, 1471424417,
1471424514), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Type = c("ASK", "BID", "ASK", "BID", "ASK", "ASK", "BID",
"BID", "BID", "ASK"), Price = c(1749.95, 1611, 1683.9, 1653,
1672, 1683.9, 1653, 1654.2, 1663, 1682)), .Names = c("Date",
"Type", "Price"), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
我们可能需要写一份问题报告。
以下是聊天后的观察结果。重要的是要注意由于 excel 导入而出现的问题。
首先,重要的是要了解 excel 如何在内部存储 date/time 值,它们(如果您打开 sheet xml 文件)看起来像42599.3750694444
其中整数部分是自 1900 年 1 月 1 日以来的天数,小数部分是当天 24 小时(86400 秒)的分数(百分比)。
当我们将其导入 R 时,您需要将此格式转换为 unix 格式(自 1970 年 1 月 1 日以来的秒数)。
显然有通常的 Floating Point approximation,如果您使用 sprintf:
获取值,它是可见的
> sprintf("%.10f",t$Date[5:8])
[1] "1471424401.0000002384" "1471424406.0000002384" "1471424406.9999997616" "1471424414.9999997616"
接下来发生的是当你 'print' 一个 POSIXct 值时,底层代码使用 C 库中的 time.h
,其中 time_t
应该是一个秒数。问题出现了 here 我认为,该值被截断为其整数部分,因此显示错误的 9:00:06 时间而不是 9:00:07.
R 中的 POSIX 类 应该处理小数秒,但您只能以 strftime
:
的自定义格式查看它们
> strftime(t$Date[5:8],"%Y/%m/%d %H:%M:%OS6")
[1] "2016/08/17 11:00:01.000000" "2016/08/17 11:00:06.000000" "2016/08/17 11:00:06.999999" "2016/08/17 11:00:14.999999"
您主要关心的是为不同的值打印同一秒,其余函数按预期工作,对第 6 行和第 7 行使用不同的值,因为它们确实不同。
我看到了两种可能的解决方法:
将列转换为数字,四舍五入,转换回 POSIXct:
t$Date <- as.POSIXct(round(as.numeric(t$Date)),origin='1970-01-01',tz='UTC')
将您的 excel sheet 导出到 csv,使用 read_csv 导入它,然后将日期列转换为日期:
z <- read.csv2("c:/Downloads/3_day_1_stock.csv", skip=1, stringsAsFactors=FALSE)
z$Date <- as.POSIXct(z$Date,format="%m/%d/%Y %H:%M:%S",tz='UTC')
对于所有情况,使用 skip=1
作为 read_* 的参数来跳过第一行,而不是您的 dput
hack,然后函数将检测到正确的列。
请在投票结束前查看聊天记录
我有以下数据:
> dput(head(q,10))
structure(list(Date = structure(c(1471424400, 1471424400, 1471424400,
1471424401, 1471424401, 1471424406, 1471424407, 1471424415, 1471424417,
1471424514), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Type = c("ASK", "BID", "ASK", "BID", "ASK", "ASK", "BID",
"BID", "BID", "ASK"), Price = c(1749.95, 1611, 1683.9, 1653,
1672, 1683.9, 1653, 1654.2, 1663, 1682)), .Names = c("Date",
"Type", "Price"), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
然后我使用了下面的代码:
data.new <- group_by(head(q,10), Date, Type) %>% summarize(price=ifelse(Type[1] == 'ASK', min(Price)
然后用
dputed<-dput(ungroup(data.new))
dput(dputed)
structure(list(Date = structure(c(1471424400, 1471424400, 1471424401,
1471424401, 1471424406, 1471424407, 1471424415, 1471424417, 1471424514
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Type = c("ASK",
"BID", "ASK", "BID", "ASK", "BID", "BID", "BID", "ASK"), price = c(1683.9,
1611, 1672, 1653, 1683.9, 1653, 1654.2, 1663, 1682)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -9L), .Names = c("Date",
"Type", "price"))
我想将其转换为宽格式,其中 日期、报价和报价是三列,行包含特定时间戳的报价和报价值。 这是我试过的:
m.q<-dcast(dputed,Date ~ Type, value.var = "price")
但是结果有重复的时间戳。请注意相邻两行中的时间戳 (2016-08-17 09:00:06)。由于 bid 和 aks 不在同一行:
> dput(m.q)
structure(list(Date = structure(c(1471424400, 1471424401, 1471424406,
1471424407, 1471424415, 1471424417, 1471424514), class = c("POSIXct",
"POSIXt"), tzone = "UTC"), ASK = c(1683.9, 1672, 1683.9, NA,
NA, NA, 1682), BID = c(1611, 1653, NA, 1653, 1654.2, 1663, NA
)), .Names = c("Date", "ASK", "BID"), row.names = c(NA, -7L), class = "data.frame")
请注意,当我使用 complete.cases() 时,我只得到 2 行而不是 3 行,因为 2016-08-17 09:00:06 被删除,因为出价和要价被分成两行相同的时间戳。
johny<- m.q[complete.cases(m.q),]
> dput(johny)
structure(list(Date = structure(c(1471424400, 1471424401), class = c("POSIXct",
"POSIXt"), tzone = "UTC"), ASK = c(1683.9, 1672), BID = c(1611,
1653)), .Names = c("Date", "ASK", "BID"), row.names = 1:2, class = "data.frame")
见下方编辑:
您提供的代码没有表现出您声称的行为:
m.q
Date ASK BID
1 2016-08-17 09:00:00 1683.9 1611.0
2 2016-08-17 09:00:01 1672.0 1653.0
3 2016-08-17 09:00:06 1683.9 NA
4 2016-08-17 09:00:07 NA 1653.0
5 2016-08-17 09:00:15 NA 1654.2
6 2016-08-17 09:00:17 NA 1663.0
7 2016-08-17 09:01:54 1682.0 NA
使用查看命令:
View(m.q)
让我们只检查该列:
m.q$Date
[1] "2016-08-17 09:00:00 UTC" "2016-08-17 09:00:01 UTC" "2016-08-17 09:00:06 UTC"
[4] "2016-08-17 09:00:07 UTC" "2016-08-17 09:00:15 UTC" "2016-08-17 09:00:17 UTC"
[7] "2016-08-17 09:01:54 UTC"
还要检查重复项:
duplicated(m.q$Date)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
没有其他方式可以告诉您您提供的数据没有重复。
编辑
按住按钮!暂时不要删除。显示器有问题。收到您的原始数据后:
library(readxl)
q <- read_excel("~/Data/3_day_1_stock.xlsx", sheet=1, skip=1)
dput(head(q, 10))
# # A tibble: 10 x 3
# Date Type Price
# <time> <chr> <dbl>
# 1 2016-08-17 09:00:00 ASK 1749.95
# 2 2016-08-17 09:00:00 BID 1611.00
# 3 2016-08-17 09:00:00 ASK 1683.90
# 4 2016-08-17 09:00:01 BID 1653.00
# 5 2016-08-17 09:00:01 ASK 1672.00
# 6 2016-08-17 09:00:06 ASK 1683.90
# 7 2016-08-17 09:00:06 BID 1653.00
# 8 2016-08-17 09:00:14 BID 1654.20
# 9 2016-08-17 09:00:17 BID 1663.00
# 10 2016-08-17 09:01:54 ASK 1682.00
第 6 行和第 7 行的日期似乎重复了。但进一步检查它们是不同的:
dput(head(q, 10))
structure(list(Date = structure(c(1471424400, 1471424400, 1471424400,
1471424401, 1471424401, 1471424406, **1471424407**__, 1471424415, 1471424417,
1471424514), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
Type = c("ASK", "BID", "ASK", "BID", "ASK", "ASK", "BID",
"BID", "BID", "ASK"), Price = c(1749.95, 1611, 1683.9, 1653,
1672, 1683.9, 1653, 1654.2, 1663, 1682)), .Names = c("Date",
"Type", "Price"), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
我们可能需要写一份问题报告。
以下是聊天后的观察结果。重要的是要注意由于 excel 导入而出现的问题。
首先,重要的是要了解 excel 如何在内部存储 date/time 值,它们(如果您打开 sheet xml 文件)看起来像42599.3750694444
其中整数部分是自 1900 年 1 月 1 日以来的天数,小数部分是当天 24 小时(86400 秒)的分数(百分比)。
当我们将其导入 R 时,您需要将此格式转换为 unix 格式(自 1970 年 1 月 1 日以来的秒数)。
显然有通常的 Floating Point approximation,如果您使用 sprintf:
获取值,它是可见的> sprintf("%.10f",t$Date[5:8])
[1] "1471424401.0000002384" "1471424406.0000002384" "1471424406.9999997616" "1471424414.9999997616"
接下来发生的是当你 'print' 一个 POSIXct 值时,底层代码使用 C 库中的 time.h
,其中 time_t
应该是一个秒数。问题出现了 here 我认为,该值被截断为其整数部分,因此显示错误的 9:00:06 时间而不是 9:00:07.
POSIX 类 应该处理小数秒,但您只能以 strftime
:
> strftime(t$Date[5:8],"%Y/%m/%d %H:%M:%OS6")
[1] "2016/08/17 11:00:01.000000" "2016/08/17 11:00:06.000000" "2016/08/17 11:00:06.999999" "2016/08/17 11:00:14.999999"
您主要关心的是为不同的值打印同一秒,其余函数按预期工作,对第 6 行和第 7 行使用不同的值,因为它们确实不同。
我看到了两种可能的解决方法:
将列转换为数字,四舍五入,转换回 POSIXct:
t$Date <- as.POSIXct(round(as.numeric(t$Date)),origin='1970-01-01',tz='UTC')
将您的 excel sheet 导出到 csv,使用 read_csv 导入它,然后将日期列转换为日期:
z <- read.csv2("c:/Downloads/3_day_1_stock.csv", skip=1, stringsAsFactors=FALSE) z$Date <- as.POSIXct(z$Date,format="%m/%d/%Y %H:%M:%S",tz='UTC')
对于所有情况,使用 skip=1
作为 read_* 的参数来跳过第一行,而不是您的 dput
hack,然后函数将检测到正确的列。