2014-12-05 16 views
20

Tôi có vector sau các giá trị gấp đôi, x, trong đó mỗi yếu tố đại diện cho một POSIX ngày thời gianĐơn giản hóa một nút POSIX với RJSONIO :: fromJSON()

x <- c(1417621083, 1417621204, 1417621384, 1417621564, 1417621623) 

Tôi đang sử dụng RJSONIO gói, và muốn tiếp tục làm như vậy.

Như một bài tập, tôi muốn chuyển đổi các giá trị này thành văn bản JSON và sau đó đọc lại chúng vào R, nhưng gặp khó khăn khi đưa biểu diễn ngày tháng vào kết quả danh sách đơn giản. Trong JSON, ngày cần phải được trong một định dạng đặc biệt để các giá trị trong x được chuyển đổi như sau:

dates <- c("/new Date(1417621083)", "/Date(1417621204)", "/Date(1417621384)", 
      "/Date(1417621564)", "/Date(1417621623)") 

Khi tôi chạy dates với một vector tùy ý thứ hai thông qua RJSONIO phân tích cú pháp, mọi thứ dường như đi thông suốt.

library(RJSONIO) 
make <- toJSON(list(date = dates, value = LETTERS)) 

Sau đó, khi tôi phân tích văn bản JSON mới bằng cách sử dụng tùy chọn stringFun với thói quen C R-json cho những ngày, kết quả là một danh sách hai yếu tố, yếu tố đầu tiên là một danh sách và thứ hai một vector nguyên tử .

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

Nhưng tôi đã mong đợi một danh sách của hai vectơ, và tôi thà có nó trong các hình thức

# $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" 

Tôi đã thử nhiều cách để đơn giản hóa kết quả từ bên trong cuộc gọi đến fromJSON(), và không ai trong số họ đã làm việc. Dưới đây là một vài nỗ lực của tôi:

Sử dụng một handler: này đơn giản hóa kết quả nhưng thất bại trong việc định dạng lại ngày

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" 

Đang cố gắng lập luậnsimplify: tôi đã cố gắng giống khác nhau của điều này và không ai làm việc.

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" 

Có cách nào để đơn giản hóa kết quả cho các ngày trong cuộc gọi đến fromJSON()?

Trả lời

5

Tôi nghĩ bạn không thể có được sự ép buộc ngày tháng và đơn giản hóa của họ thành véc tơ trong cùng một thời điểm. Vì một lý do đơn giản là điều này chưa được thực hiện trong RJSONIO. Thật vậy khi bạn đề cập đến việc đơn giản hóa được thực hiện bằng cách sử dụng một cờ: StrictLogical, StrictNumericStrictCharacter tạo ra các lôgic, số hoặc ký tự vectơ. Có thể bạn nên liên hệ với người duy trì để thêm StrictPosixct cờ cho POSIXct ngày.

Sử dụng stringFun không thể trợ giúp vì nó nhận được phần tử vô hướng (chuỗi ký tự) và không biết các phần tử vectơ khác. Bạn có thể kiểm tra điều này bằng cách định nghĩa một hàm R như tham số stringFun và đặt một trình duyệt bên trong nó.

convertJSONDate <- 
    function(x) 
    { 
    if(grepl('Date',x)){ 
     val <- sub('.*[(]([0-9]+).*','\\1',x) 
     return(structure(as.numeric(val)/1000, class = c("POSIXct", "POSIXt"))) 
    } 
    x 
    } 

Tôi đoán bạn muốn thực hiện việc ép buộc/đơn giản hóa khi bạn phân tích cú pháp của bạn vì lý do hiệu suất. Tôi sẽ sử dụng một chiến lược khác:

  1. Tôi buộc các giá trị số của tôi vào POSIXct và tôi sẽ lưu trữ chúng dưới dạng ký tự trong một ngày được định dạng tốt. Điều này là tốt hơn sau đó đặc biệt (xấu xí) "ngày mới (.., ngày") định dạng ngày RJSONIO. Hãy nhớ rằng định dạng json là định dạng chuẩn có thể được phân tích cú pháp bằng các ngôn ngữ khác (python, js, ..)
  2. Sau đó phân tích ngày của tôi làm ký tự bình thường và sử dụng gói fasttime nhanh để ép buộc nó vào vector POSIXct.

đây một số mã để hiển thị này:

## 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

Từ read giá trị mà tôi đoán là điểm khởi đầu mong muốn ... Đây là một cách:

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

Class-ép buộc là loại "bẩn" nhưng tôi đã loay hoay một lúc các chiến lược khác (thất bại), ví dụ unlist, sapply(read,"[[",1), sapply(read, c)), để bảo quản thuộc tính, vì vậy tôi quyết định xuống dưới bùn với R và xoay búa hạng.

0

Vì tiền thưởng đã hết hạn và nó không thể được thực hiện trong RJSONIO (hoặc có vẻ như vậy), tôi sẽ áp dụng phương pháp thay thế này trong trường hợp bất kỳ người dùng nào khác gặp phải vấn đề này và cần một giải pháp.

Gói jsonlite có thể thực hiện thao tác này dễ dàng.Tất cả những gì chúng ta phải làm là thêm lớp POSIXt vào vectơ số và chỉ định "mongo" cho trình phân tích cú pháp trong hàm không được xuất asJSON.

# 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" 
Các vấn đề liên quan