如何将传感器API返回的嵌套JSON列表转换为DataFrame?
问题:将Ecowitt传感器历史数据转换为指定格式的DataFrame
我正在从多个传感器(这里以2个为例测试)导入数据,最终要生成一个包含4列的DataFrame:每个传感器对应两列,一列是数据采集时间,另一列是传感器数据。API起始地址为https://api.ecowitt.net/api/v3/device/history(含密钥无法提供完整链接)。
现有可运行的API请求代码
response <- httr::GET(url_complete_noDates, query = list(start_date = "2022-07-01 00:00:00", end_date = "2022-07-01 02:00:00")) jsonRespText <- content(response, as = "text") j <- fromJSON(jsonRespText)
尝试过但未解决的转换代码
j_data <- j$data df_json1 <- as_tibble(j_data, validate = F) temp_unnest <- df_json1 %>% unnest(cols = names(df_json1))
解析后的JSON结构(dput输出)
list(code = 0L, msg = "success", time = "1673535777", data = list( soil_ch1 = list(soilmoisture = list(unit = "%", list = list( `1656655200` = "38", `1656657000` = "38", `1656658800` = "38", `1656660600` = "38", `1656662400` = "38"))), soil_ch2 = list( soilmoisture = list(unit = "%", list = list(`1656655200` = "48", `1656657000` = "48", `1656658800` = "48", `1656660600` = "48", `1656662400` = "48")))))
注:其中的数字时间值是从1970-01-01 00:00 MDT开始计算的时间戳(秒),每个时间戳 = 数值的元素是需要放入DataFrame的时间/数据点。
解决方案
通过循环处理每个传感器数据,将时间戳转换为可读时间后合并成目标格式:
library(tidyverse) library(lubridate) # 提取传感器数据部分 sensor_data <- j$data # 定义单个传感器数据处理函数 process_sensor <- function(sensor_name, sensor_data) { # 提取时间戳和对应数值 data_points <- sensor_data$soilmoisture$list # 转换为数据框:时间戳转日期时间,数值转数值型 tibble( !!paste0(sensor_name, "_time") := as_datetime(as.numeric(names(data_points))), !!paste0(sensor_name, "_value") := as.numeric(unlist(data_points)) ) } # 批量处理所有传感器并按时间合并 result_df <- map2_dfr(names(sensor_data), sensor_data, process_sensor) %>% arrange(soil_ch1_time) # 按时间排序(可选,确保数据顺序一致)
结果说明
最终生成的result_df包含4列:soil_ch1_time、soil_ch1_value、soil_ch2_time、soil_ch2_value,完全符合需求。后续新增传感器时,代码会自动处理并添加对应的列,无需修改核心逻辑。
内容的提问来源于stack exchange,提问作者JerryN
相关产品推荐
相关产品推荐

