将两个列表组合成 R 中的 JSON

Combining two lists into a JSON in R

我有两个列表 - test.segments - 代表时间戳,第二个 - test.coords - 代表 lat/lon 坐标。每个列表中的元素数量是相等的——所以理论上两者应该很容易组合。

> test.segments
[[1]]
[1] 4380.000 4388.125 4396.250 4404.375 4412.500 4420.625 4428.750 4436.875 4445.000

[[2]]
[1] 4448.000 4449.667 4451.333 4453.000

[[3]]
 [1] 4696.000 4716.444 4736.889 4757.333 4777.778 4798.222 4818.667 4839.111 4859.556 4880.000

> test.coords
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
          [,1]     [,2]
 [1,] 19.93882 50.06548
 [2,] 19.93882 50.06548
 [3,] 19.93881 50.06556
 [4,] 19.93885 50.06561
 [5,] 19.93885 50.06562
 [6,] 19.93885 50.06561
 [7,] 19.93885 50.06561
 [8,] 19.93885 50.06561
 [9,] 19.93885 50.06561



[[2]]
[[2]][[1]]
[[2]][[1]][[1]]
         [,1]     [,2]
[1,] 19.91947 50.07203
[2,] 19.91947 50.07203
[3,] 19.91947 50.07203
[4,] 19.91947 50.07203



[[3]]
[[3]][[1]]
[[3]][[1]][[1]]
          [,1]     [,2]
 [1,] 19.93553 50.06572
 [2,] 19.93554 50.06568
 [3,] 19.93554 50.06568
 [4,] 19.93551 50.06574
 [5,] 19.93537 50.06576
 [6,] 19.93403 50.06723
 [7,] 19.93394 50.06734
 [8,] 19.93393 50.06738
 [9,] 19.93393 50.06738
[10,] 19.93393 50.06738

我的目标是将两个列表合并为下面的 json 格式(注意:键 vendor 应始终为 0)以便 startTime 代表第一个段,endTime表示最后一段,而segments[lat, lon, corresponding segment]

的数组

我曾尝试使用 jsonlite 库,但这会切断小数点后 4 位的坐标,我不确定如何合并这两个列表。如有任何建议,我们将不胜感激。

[
  {
    "vendor": 0,
    "startTime": 4380,
    "endTime": 4445,
    "segments": [
      [19.93882, 50.06548, 4380],
      [19.93882, 50.06548, 4388.125],
      [19.93881, 50.06556, 4396.250],
      [19.93885, 50.06561, 4404.375],
      [19.93885, 50.06562, 4412.500],
      [19.93885, 50.06561, 4420.625],
      [19.93885, 50.06561, 4428.750],
      [19.93885, 50.06561, 4436.875],
      [19.93885, 50.06561, 4445]
    ]
  },
  {
    "vendor": 0,
    "startTime": 4448,
    "endTime": 4453,
    "segments": [
      [19.91947, 50.07203, 4448],
      [19.91947, 50.07203, 4449.667],
      [19.91947, 50.07203, 4451.333],
      [19.91947, 50.07203, 4453]
    ]
  },
  {
    "vendor": 0,
    "startTime": 4696,
    "endTime": 4880,
    "segments": [
      [19.93553, 50.06572, 4696],
      [19.93554, 50.06568, 4716.444],
      [19.93554, 50.06568, 4736.889],
      [19.93551, 50.06574, 4757.333],
      [19.93537, 50.06576, 4777.778],
      [19.93403, 50.06723, 4798.222],
      [19.93394, 50.06734, 4818.667],
      [19.93393, 50.06738, 4839.111],
      [19.93393, 50.06738, 4859.556],
      [19.93393, 50.06738, 4880]
    ]
  }
]

这是上面使用的数据样本:

> dput(test.segments)
list(c(4380, 4388.125, 4396.25, 4404.375, 4412.5, 4420.625, 4428.75, 
4436.875, 4445), c(4448, 4449.66666666667, 4451.33333333333, 
4453), c(4696, 4716.44444444444, 4736.88888888889, 4757.33333333333, 
4777.77777777778, 4798.22222222222, 4818.66666666667, 4839.11111111111, 
4859.55555555556, 4880))

> dput(test.coords)
list(list(list(structure(c(19.9388183333333, 19.9388183333333, 
19.93881, 19.938845, 19.9388483333333, 19.9388516666667, 19.9388516666667, 
19.9388516666667, 19.9388516666667, 50.0654816666667, 50.0654816666667, 
50.0655566666667, 50.0656116666667, 50.065615, 50.0656083333333, 
50.0656066666667, 50.0656066666667, 50.0656066666667), .Dim = c(9L, 
2L)))), list(list(structure(c(19.9194666666667, 19.9194666666667, 
19.9194666666667, 19.9194666666667, 50.0720283333333, 50.0720283333333, 
50.0720283333333, 50.0720283333333), .Dim = c(4L, 2L)))), list(
    list(structure(c(19.9355333333333, 19.93554, 19.93554, 19.9355116666667, 
    19.9353733333333, 19.9340316666667, 19.9339433333333, 19.9339266666667, 
    19.9339266666667, 19.9339266666667, 50.06572, 50.06568, 50.06568, 
    50.0657416666667, 50.065765, 50.06723, 50.0673366666667, 
    50.0673833333333, 50.0673816666667, 50.0673816666667), .Dim = c(10L, 
    2L)))))

我们可以使用purrrmap2()函数将两个列表'iterate'并列,然后组合成我们想要的,然后转换为json:

library(purrr)

j <- coords %>% 
  map2(segments, ~{

    list(vendor = 0,
         startTime = min(.y),
         endTime = max(.y),
         segments = cbind(.x[[1]][[1]], .y)
    )
  }) %>% 
  jsonlite::toJSON(auto_unbox = T, digits = NA)
j
#> [{"vendor":0,"startTime":4380,"endTime":4445,"segments":[[19.9388183333333,50.0654816666667,4380],[19.9388183333333,50.0654816666667,4388.125],[19.93881,50.0655566666667,4396.25],[19.938845,50.0656116666667,4404.375],[19.9388483333333,50.065615,4412.5],[19.9388516666667,50.0656083333333,4420.625],[19.9388516666667,50.0656066666667,4428.75],[19.9388516666667,50.0656066666667,4436.875],[19.9388516666667,50.0656066666667,4445]]},{"vendor":0,"startTime":4448,"endTime":4453,"segments":[[19.9194666666667,50.0720283333333,4448],[19.9194666666667,50.0720283333333,4449.66666666667],[19.9194666666667,50.0720283333333,4451.33333333333],[19.9194666666667,50.0720283333333,4453]]},{"vendor":0,"startTime":4696,"endTime":4880,"segments":[[19.9355333333333,50.06572,4696],[19.93554,50.06568,4716.44444444444],[19.93554,50.06568,4736.88888888889],[19.9355116666667,50.0657416666667,4757.33333333333],[19.9353733333333,50.065765,4777.77777777778],[19.9340316666667,50.06723,4798.22222222222],[19.9339433333333,50.0673366666667,4818.66666666667],[19.9339266666667,50.0673833333333,4839.11111111111],[19.9339266666667,50.0673816666667,4859.55555555556],[19.9339266666667,50.0673816666667,4880]]}]

您也可以在 base R 中执行此操作,尽管 @GGamba 的答案可能更快。

library(jsonlite)

test.segments = list(c(4380, 4388.125, 4396.25, 4404.375, 4412.5, 4420.625, 4428.75, 
                       4436.875, 4445), 
                     c(4448, 4449.66666666667, 4451.33333333333, 4453), 
                     c(4696, 4716.44444444444, 4736.88888888889, 4757.33333333333, 
                       4777.77777777778, 4798.22222222222, 4818.66666666667, 4839.11111111111, 
                       4859.55555555556, 4880))

test.coords = list(
  list(
    list(
      structure(c(19.9388183333333, 19.9388183333333, 
                  19.93881, 19.938845, 19.9388483333333, 19.9388516666667, 19.9388516666667, 
                  19.9388516666667, 19.9388516666667, 50.0654816666667, 50.0654816666667, 
                  50.0655566666667, 50.0656116666667, 50.065615, 50.0656083333333, 
                  50.0656066666667, 50.0656066666667, 50.0656066666667), .Dim = c(9L, 2L)))), 
  list(
    list(
      structure(c(19.9194666666667, 19.9194666666667, 19.9194666666667, 19.9194666666667, 
                  50.0720283333333, 50.0720283333333, 50.0720283333333, 50.0720283333333), 
                .Dim = c(4L, 2L)))), 
  list(
    list(
      structure(c(19.9355333333333, 19.93554, 19.93554, 19.9355116666667, 19.9353733333333, 
                  19.9340316666667, 19.9339433333333, 19.9339266666667, 19.9339266666667, 
                  19.9339266666667, 50.06572, 50.06568, 50.06568, 50.0657416666667, 
                  50.065765, 50.06723, 50.0673366666667, 
                  50.0673833333333, 50.0673816666667, 50.0673816666667), .Dim = c(10L, 2L)))))

tmp = lapply(seq_along(test.segments), function(i) {
  x = test.segments[[i]]
  y = test.coords[[i]][[1]][[1]]
  y = unname(cbind(y, x))
  list(vendor=0, startTime=min(x), endTime=max(x), segments=y)
})

j = toJSON(tmp, auto_unbox=TRUE)