使用RJSONIO::fromJSON()简化POSIX节点

21
我有一个双精度浮点数向量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))

然后,当我使用R-json C例程中的stringFun选项来解析新的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"

尝试简化参数: 我尝试了几种不同的方法,但都没有成功。

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() 的日期结果?
3个回答

5
我认为你不能同时获得日期的强制性和将其简化为向量。这是因为目前的 RJSONIO 尚未实现此功能。正如你所提到的,简化是使用以下标志之一完成的: StrictLogical, StrictNumericStrictCharacter,它们创建逻辑、数字或字符向量。也许你应该联系维护者,添加 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时进行强制/简化以提高性能。我会使用不同的策略:
  1. 我将我的数字值强制转换为POSIXct,并将它们存储为格式良好的日期字符。这比特殊(丑陋的)“new Date(..,date”)RJSONIO日期格式更好。请记住,JSON格式是一个标准格式,可以被其他语言(Python,JS等)解析。
  2. 然后将我的日期解析为普通字符,并使用快速的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"

3

从我猜测是所需起始点的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"

类强制转换有点“肮脏”,但我已经尝试了很多其他(失败的)策略,例如unlistsapply(read,"[[",1)sapply(read, c)等,用于保留属性,因此我决定在R中下沉并使用类锤。


1

由于赏金已经过期,而且目前似乎无法在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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接