在R中基于时间合并无共同列的两个Dataframe方法问询
合并时间序列DataFrame并绘制分面图
问题描述
我有两个Dataframe(A和B),二者均包含time列但无其他共同列,B的时间行数远少于A(二者仅包含单日数据)。需要将B的所有行合并入A,无对应值的列显示NA,用于制作ggplot分面图。尝试过join、行绑定及bayesbio包的nearestTime函数,但均无效。
A和B的结构如下:
# Dataframe A结构 structure(list(time = structure(c(-2209038596.86, -2209038594.86, -2209038592.86, -2209038590.86, -2209038588.86, -2209038586.86, -2209038584.86, -2209038582.86, -2209038580.86, -2209038578.86), tzone = "UTC", class = c("POSIXct", "POSIXt" )), pH = c(7.13642, 7.12116, 7.12116, 7.13133, 7.12625, 7.12625, 7.12625, 7.13133, 7.11608, 7.12625), oxygen = c(6.13248, 6.11996, 6.10745, 6.11996, 6.11996, 6.09493, 6.09493, 6.08242, 6.08242, 6.08242)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame")) # Dataframe B结构 structure(list(time = structure(c(-2209038180, -2209035240, -2209034340, -2209033440, -2209031640), tzone = "UTC", class = c("POSIXct", "POSIXt")), DOC = c(5001, 36787, 20835, 13085, 8344), Temp = c(22.2, 20, 22.5, 22.6, 23), conductivity = c(2.16, 2.29, 2.37, 2.42, 2.49), flow = c(15, 15, 15, 15, 15)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))
注:所有时间被设为1899年,在POSIXct中显示为负数。合并后需保留所有时间值和列,同时希望x轴显示小时和分钟而非完整时间。
解决方案
1. 合并两个DataFrame
使用dplyr包的full_join()函数,它会保留两个DataFrame的所有行,无匹配的列自动填充NA,完全符合需求:
library(dplyr) # 按time列合并所有行 combined_df <- full_join(A, B, by = "time")
合并后,A独有的行中B的列(DOC、Temp等)为NA,B独有的行中A的列(pH、oxygen)为NA,所有原始时间点都被保留。
2. 处理时间格式与绘制分面图
为了让x轴只显示小时和分钟,同时制作分面图,建议先将数据转为长格式,再用ggplot2配置:
library(ggplot2) library(scales) library(tidyr) # 转为长格式,方便分面 long_df <- combined_df %>% pivot_longer(cols = -time, names_to = "variable", values_to = "value") # 绘制分面图,设置x轴显示时分 ggplot(long_df, aes(x = time, y = value)) + geom_point(size = 1.5) + # 按变量分面,y轴自适应范围 facet_wrap(~variable, scales = "free_y", ncol = 2) + # 设置x轴刻度为小时+分钟,每1小时显示一个刻度 scale_x_datetime(labels = date_format("%H:%M"), breaks = date_breaks("1 hour")) + labs(x = "时间(时:分)", y = "数值") + theme_minimal()
为何之前的方法无效?
bind_rows():仅简单追加行,不会匹配time列,导致同一时间的行无法合并,不符合需求。- 普通
join(如inner_join):仅保留time匹配的行,会丢失A或B独有的时间点。 nearestTime():用于匹配最近时间点合并,而非保留所有原始时间点,不适用当前场景。
内容的提问来源于stack exchange,提问作者3wF23Xyj
相关产品推荐
相关产品推荐

