>我有以下双精度值向量,x
,其中每个元素代表一个 POSIX 日期时间
x <- c(1417621083, 1417621204, 1417621384, 1417621564, 1417621623)
我正在使用 RJSONIO 软件包,并希望继续这样做。
作为练习,我想将这些值转换为 JSON 文本,然后再次将它们读回 R,但在将日期时间表示形式转换为一个漂亮的简化列表结果时遇到问题。在 JSON 中,日期需要采用特殊格式,以便将 x
中的值转换为以下内容:
dates <- c("/new Date(1417621083)", "/Date(1417621204)", "/Date(1417621384)",
"/Date(1417621564)", "/Date(1417621623)")
当我通过 RJSONIO 解析器使用第二个任意向量运行dates
时,一切似乎都很顺利。
library(RJSONIO)
make <- toJSON(list(date = dates, value = LETTERS))
然后,当我使用 stringFun
选项和 R-json C 例程解析新的 JSON 文本时,结果是一个双元素列表,第一个元素是列表,第二个元素是原子向量。
(read <- fromJSON(make, stringFun = "R_json_dateStringOp"))
# $date
# $date[[1]]
# [1] "2014-12-03 07:38:03 PST"
#
# $date[[2]]
# [1] "2014-12-03 07:40:04 PST"
#
# $date[[3]]
# [1] "2014-12-03 07:43:04 PST"
#
# $date[[4]]
# [1] "2014-12-03 07:46:04 PST"
#
# $date[[5]]
# [1] "2014-12-03 07:47:03 PST"
#
#
# $value
# [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
# [14] "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
但是我期待两个向量的列表,我宁愿以
# $date
# [1] "2014-12-03 07:38:03 PST" "2014-12-03 07:40:04 PST"
# [3] "2014-12-03 07:43:04 PST" "2014-12-03 07:46:04 PST"
# [5] "2014-12-03 07:47:03 PST"
#
# $value
# [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q"
# [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
我尝试了几种方法来简化调用fromJSON()
中的结果,但没有一种奏效。以下是我的一些尝试:
使用处理程序:这简化了结果,但无法重新格式化日期
h1 <- basicJSONHandler(simplify = TRUE)
fromJSON(make, handler = h1, stringFun = "R_json_dateStringOp")
# $date
# [1] "/new Date(1417621083)" "/Date(1417621204)"
# [3] "/Date(1417621384)" "/Date(1417621564)"
# [5] "/Date(1417621623)"
#
# $value
# [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
# [14] "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
尝试simplify
论点:我尝试了几种不同的品种,但没有一种奏效。
fromJSON(make, simplify = StrictCharacter)
# $date
# [1] "/new Date(1417621083)" "/Date(1417621204)"
# [3] "/Date(1417621384)" "/Date(1417621564)"
# [5] "/Date(1417621623)"
#
# $value
# [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
# [14] "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
有没有办法简化调用fromJSON()
中日期的结果?
我认为您无法同时获得日期的强制和简化为向量。原因很简单,这(尚未(在 RJSONIO
中实现.事实上,正如你提到的,简化是使用一个标志完成的:StrictLogical
、StrictNumeric
和StrictCharacter
,它们创建了逻辑、数字或字符向量。也许您应该联系维护者StrictPosixct
为POSIXct
日期添加标志。
使用 stringFun
无济于事,因为它接收标量元素(字符串(并且不知道其他矢量元素。您可以通过将 R 函数定义为 stringFun 参数并在其中放置浏览器来检查这一点。
convertJSONDate <-
function(x)
{
if(grepl('Date',x)){
val <- sub('.*[(]([0-9]+).*','\1',x)
return(structure(as.numeric(val)/1000, class = c("POSIXct", "POSIXt")))
}
x
}
我猜您想在出于性能原因解析 json 时进行强制/简化。我会使用不同的策略:
- 我将我的数值强制为 POSIXct,并将它们作为字符存储在格式良好的日期中。这比特殊的(丑陋的("新日期(..,日期"(RJSONIO 日期格式更好。请记住,json格式是一种标准格式,可以被其他语言(python,js,..(解析。
- 然后将我的日期解析为普通字符,我使用快速
fasttime
包将其强制为 POSIXct 向量。
这里有一些代码来显示这一点:
## coerce x to dates a well formatted dates
dd <- as.character(as.POSIXct(x,origin = '1970-01-01' , tz = "UTC"))
## read it again in a fast way
fastPOSIXct(fromJSON(make)$date)
[1] "2014-12-03 16:38:03 CET" "2014-12-03 16:40:04 CET" "2014-12-03 16:43:04 CET" "2014-12-03 16:46:04 CET" "2014-12-03 16:47:03 CET"
从我猜的read
值是所需的起点......这是一种方式:
> dd <- sapply(read, c)
> class(dd) <- "POSIXct"
> dd
[1] "2014-12-03 07:38:03 PST" "2014-12-03 07:40:04 PST" "2014-12-03 07:43:04 PST"
[4] "2014-12-03 07:46:04 PST" "2014-12-03 07:47:03 PST"
阶级胁迫有点"肮脏",但我已经尝试过很多其他(失败的(策略,例如 unlist
,sapply( read,"[[",1)
,sapply(read, c)
(,为了保留属性,所以我决定和R一起陷入泥泞并挥舞职业锤。
由于赏金已过期,事实证明目前无法在RJSONIO
中完成此操作(或者看起来如此(,我将将其作为另一种替代方法,以防任何其他用户遇到此问题并需要解决方案。
包jsonlite
可以轻松执行此操作。 我们所要做的就是将 POSIXt
类添加到数字向量中,并在非导出函数 asJSON
中为解析器指定"mongo"
。
# unloadNamespace(RJSONIO) ## to avoid confusion between packages
library(jsonlite)
x <- c(1417621083, 1417621204, 1417621384, 1417621564, 1417621623)
class(x) <- "POSIXt"
data <- list(dates = x, values = letters[1:5])
json <- jsonlite:::asJSON(data, POSIXt = "mongo")
fromJSON(json)
# $dates
# [1] "2014-12-03 07:38:03 PST" "2014-12-03 07:40:04 PST"
# [3] "2014-12-03 07:43:04 PST" "2014-12-03 07:46:04 PST"
# [5] "2014-12-03 07:47:03 PST"
#
# $values
# [1] "a" "b" "c" "d" "e"