如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?
Posted
技术标签:
【中文标题】如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?【英文标题】:How to plot a time-series scatterplot showing missing y-axis values as gaps? 【发布时间】:2021-10-22 06:24:03 【问题描述】:我正在尝试创建一个散点图,其中 x 轴为日期/时间,y 轴为盐度。但是,由于设备故障,有些日期/时间点没有盐度值,但我仍然需要这些时间部分显示在我的图表上,以帮助解释我正在查看的生态模式。谁能建议如何在图表上显示这些缺失的部分?
我当前的数据代码和未显示缺失值的绘图。
编辑 我的数据有明确的缺失值,其中数据由于记录器错误而被删除,但被列为“NA”(见图)。不幸的是,我每半小时收集数千个数据点,因此很难显示所有数据。
Screenshot of data showing 'NA' values
OY1_AllTimes <- read_csv("~/Documents/TAMUG_Thesis/Rollover_Pass_Data/Logger/RP_LoggerData_OY1_AllTimes.csv")
summary(OY1_AllTimes)
OY1_AllTimes$Date_time<-paste(OY1_AllTimes$Date, OY1_AllTimes$Time)
summary(OY1_AllTimes$Date_time)
date_time_OY1_AllTimes<-as.POSIXct(OY1_AllTimes$Date_time, format="%m/%d/%Y %H:%M")
date_time_OY1_AllTimes
date_time2_OY1_AllTimes<-as.factor(date_time_OY1_AllTimes)
date_time2_OY1_AllTimes
summary(OY1_AllTimes)
Summary of OY1_AllTimes
p_OY1_AllTimes <- ggplot(data = OY1_AllTimes, aes(x=date_time2_OY1_AllTimes, y=Salinity)) + geom_point() + theme_classic()+
scale_x_discrete("Date", breaks=c("0019-10-04 09:30:00", "0019-11-01 05:00:00", "0019-12-01 00:00:00", "0020-01-01 00:00:00", "0020-02-01 00:00:00",
"0020-03-01 00:00:00","0020-04-01 00:00:00", "0020-05-01 00:00:00", "0020-06-01 00:00:00"),
labels=c("10/2019", "11/2019", "12/2019", "1/2020", "2/2020", "3/2020", "4/2020", "5/2020", "6/2020"))+ylab("Salinity")+ggtitle("OY1")
p_OY1_AllTimes
Scatterplot of OY1 without missing values
基本上我希望看到上面的散点图,其中的间隙表示没有盐度数据的时期,以便日期/时间尺度是连续的。
数据的子样本:
# A tibble: 50 x 5
Site Date Time Salinity Date_time
<chr> <chr> <time> <dbl> <chr>
1 OY1 10/4/19 09:30 NA 10/4/19 09:30:00
2 OY1 10/4/19 10:00 NA 10/4/19 10:00:00
3 OY1 10/4/19 10:30 0.891 10/4/19 10:30:00
4 OY1 10/4/19 11:00 0.961 10/4/19 11:00:00
5 OY1 10/4/19 11:30 1.02 10/4/19 11:30:00
6 OY1 10/4/19 12:00 1.10 10/4/19 12:00:00
7 OY1 10/4/19 12:30 1.19 10/4/19 12:30:00
8 OY1 10/4/19 13:00 1.27 10/4/19 13:00:00
9 OY1 10/4/19 13:30 1.33 10/4/19 13:30:00
10 OY1 10/4/19 14:00 1.42 10/4/19 14:00:00
# … with 40 more rows```
【问题讨论】:
我认为您应该使用date_time_OY1_AllTimes
变量而不是转换后的因子版本,并删除scale_x_discrete
。然后你应该得到一个基于底层时间戳的连续日期轴,而不是按顺序堆叠。
@JonSpring 不幸的是,这仍然会生成一个删除我所有“NA”数据的图表。我需要将这些显示为时间序列中的空白。
你能解释一下“将这些显示为间隙”是什么意思吗?这是否意味着您想要每个缺失点的轴上的文本?我原以为我下面的答案是“显示差距”,时间轴上有一个部分缺少点,但也许我还不明白。
@JonSpring 所以我想要你上面显示的内容,但是当我尝试这样做时,R 仍在删除我的缺失值的行并给我其他错误。我成功地为第一个图表运行了您的代码,但收到了警告消息:删除了包含缺失值 (geom_point) 的 3831 行。对于您的第二张图,我收到一个未使用的争论(data_labels =“%b\n'%y”)的错误。对于您的第三张图,我收到错误“中断”和“标签”必须具有相同的长度。
您看到的警告是因为您的数据在 ggplot 中用于 3831 行数据的至少一列中包含 NA。如果这是您所期望的,那可能会很好。如果您的 Date_time
列不是日期时间数据(通常是 POSIXct),则可能会出现第二个错误。也许是性格或因素数据? (什么是str(OY1_AllTimes$Date_time)
)?在任何情况下,如果您可以在问题中包含代码形式的数据样本,那么提供帮助会更容易,如下所述:***.com/questions/5963269/…
【参考方案1】:
这是我尝试用一些我们都可以运行的可重现代码来证明这一点。
这里有一些任意的假数据。重要的是它在时间戳上有很大的差距,因为我从 100:399 中删除了几百行。此时,timestamp
被存储为日期时间数据,在最典型的“POSIXct”变体中,与您的date_time_OY1_AllTimes
变量相同。
set.seed(42)
my_fake_data <- data.frame(timestamp = as.POSIXct("2021-01-01 00") + cumsum(runif(1000, 0, 6E4)), reading = cumsum(rnorm(1000)))
my_fake_data <- my_fake_data[c(1:99, 400:1000),]
ggplot2 中的典型情况是使用该 POSIXct 值进行绘图。你会看到差距。 ggplot2 将时间戳映射到 x 轴,并为我们选择默认标签。
ggplot(my_fake_data, aes(timestamp, reading)) +
geom_point()
如果我们想要每月标签,我们可以指定它以及我们想要查看的格式:
... + scale_x_datetime(date_breaks = "month",
date_labels = "%b\n'%y", minor_breaks = NULL)
在您的示例中,时间戳已转换为因子,这保留了它们的顺序,但它会及时将它们从上下文中删除,因此间隙已经消失。在这里,我手动添加了离散标签,但它们与我的数据点不再有明确的时间关系。我可以让他们说出我想说的任何内容,除非我手动调整它们,否则它们会出错。
ggplot(my_fake_data, aes(as.factor(timestamp), reading)) +
geom_point() +
scale_x_discrete(breaks = as.factor(my_fake_data[1+100*0:7,1]),
labels = format(
seq.Date(as.Date("2021-01-01"),
as.Date("2021-08-01"), by = "month"), "%b %Y"))
【讨论】:
【参考方案2】:很难说出您的数据的真实情况,我假设您有一个隐式缺失数据问题。
这意味着,您有一个缺少观察的 data.frame/time 序列。但问题是,这些缺失值并未明确作为 NA 给出。相反,这些都被忽略了。
具有 NA 的时间序列如下所示:
1.1.2021 14:00
1.1.2021 15:00
1.1.2021 16:00
1.1.2021 17:00
1.1.2021 NA
1.1.2021 19:00
我猜你的问题是这样的:
1.1.2021 14:00
1.1.2021 15:00
1.1.2021 16:00
1.1.2021 17:00
1.1.2021 19:00
所以不同的是,18:00 时间步没有 NA 值。但是,你当然知道有一个缺失值(这就是为什么它被称为隐式缺失值)。
假设您有一个规则间隔的时间序列(即以规则间隔测量的值,例如 1h),您可以使用 tsibble 包将隐式缺失值转换为正常缺失值,其中您有NAs 是系列。
这是一个简单的例子(因为我没有你的数据):
library("tsibble")
# Read in your data as tsibble
data_example <- tsibble(
year = c(2016, 2017, 2018, 2019, 2021, 2022),
measure = sample(1:10, size = 6),
index = year
)
# Take a look at the data
data_example
# Use the fill_gaps function of tsibble
data_na <- fill_gaps(data_example, .full = TRUE)
# You can see now, the implicit missing year 2020 is now added as NA
data_na
当然,您也可以对各种不同的规则间隔时间序列数据(15 秒、分钟、小时、月...)执行此操作。您只需在创建 tsibble 对象时定义时间步。
现在绘图很容易:
library("ggplot2")
ggplot(data = data_na) + geom_point( aes(year, measure))
这会给你这个情节:
如您所见,如您所愿,该系列已绘制,但情节中没有 2020 年。如果您想更加关注缺失的数据,还可以使用 imputeTS 包。
library("imputeTS")
ggplot_na_distribution(data_na)
这将如下所示:
这只是一个小的示例时间序列,对于更大的时间序列,这看起来像例如这个情节:
【讨论】:
抱歉不清楚,实际上我的 R 数据中有明确的缺失值显示为“NA”(我将在上面附上一张照片)。但是,当我尝试绘制这些 R 时,仍然会删除包含缺失值的行。在这种情况下 tsibble 还能用吗?以上是关于如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?的主要内容,如果未能解决你的问题,请参考以下文章