长到宽格式转换会提供重复的时间标识符行

时间:2016-08-24 12:48:31

标签: r dplyr reshape2

请在投票结束前查看聊天记录

我有以下数据:

> 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)。由于哪个出价和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")

enter image description here

请注意,当我使用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")

2 个答案:

答案 0 :(得分:3)

见下面的编辑:

您提供的代码未显示您声明的行为:

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命令:

View(m.q)

enter image description here

我们只检查该列:

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"))

我们可能要写一份问题报告。

答案 1 :(得分:1)

以下是聊天会话后的观察结果。重要的是要注意由于excel导入而出现问题。

首先,了解excel如何在内部存储日期/时间值非常重要,它们(如果您打开工作表xml文件)看起来像42599.3750694444,其中整数部分是天数自1900年1月1日起,小数部分是当天24小时(86400秒)的派系(百分比)。

将它导入R时会发生什么情况,您需要从此格式转换为unix格式(1970年1月1日以来的秒数)。

很明显,如果你使用sprintf获取值,那么常见的Floating Point approximation是可见的:

> sprintf("%.10f",t$Date[5:8])
[1] "1471424401.0000002384" "1471424406.0000002384" "1471424406.9999997616" "1471424414.9999997616"

接下来会发生什么,当你打印&#39;一个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行的不同值,因为它们确实不同。

我看到两种可能的解决方法:

  1. 将列转换为数字,将其四舍五入,转换回POSIXct:

    t$Date <- as.POSIXct(round(as.numeric(t$Date)),origin='1970-01-01',tz='UTC')
    
  2. 将您的Excel工作表导出到csv,使用read_csv导入它,然后将Date列转换为日期:

    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')
    
  3. 对于所有情况,请使用dput作为参数read_ *跳过第一行,而不是skip=1 hack,然后函数将检测正确的列。