识别并绘制被 NA 包围的数据点
Identify and plot datapoints surrounded by NAs
我正在使用 ggplot2
和 geom_line()
制作大量时间序列的线图。数据集有大量的缺失值,我很高兴没有在缺失的部分画线,因为这看起来很尴尬。
我的问题是未绘制被 NA 包围的单个非 NA 数据点(或序列 beginning/end 的点,另一侧为 NA)。一个潜在的解决方案是为所有观察添加 geom_point()
,但这会使我的文件大小增加十倍,并使情节更难阅读。
因此,我只想识别那些未显示 geom_line()
的数据点,并仅为那些 添加点。有没有直接的方法来识别这些点?
我的数据目前是长格式的,下面的MWE可以作为说明。我想识别第 1 行和第 7 行,以便绘制它们:
library(ggplot2)
set.seed(1)
dat <- data.frame(time=rep(1:5,2),country=rep(1:2,each=5),value=rnorm(10))
dat[c(2,6,8),3] <- NA
ggplot(dat) + geom_line(aes(time,value,group=country))
> dat
time country value
1 1 1 -0.6264538
2 2 1 NA
3 3 1 -0.8356286
4 4 1 1.5952808
5 5 1 0.3295078
6 1 2 NA
7 2 2 0.4874291
8 3 2 NA
9 4 2 0.5757814
10 5 2 -0.3053884
你的意思是这样的吗?
library(tidyverse)
dat %>%
na.omit() %>%
ggplot() +
geom_line(aes(time, value, group = country))
您可以使用 zoo::rollapply
函数创建一个新列,其值仅以 NA 结尾。然后你可以简单地绘制这些点。例如:
library(zoo)
library(ggplot2)
foo <- data.frame(time =c(1:11), value = c(1 ,NA, 3, 4, 5, NA, 2, NA, 4, 5, NA))
# Perform sliding window processing
val <- c(NA, NA, foo$value, NA, NA) # Add NA at the ends of vector
val <- rollapply(val, width = 3, FUN = function(x){
if (all(is.na(x) == c(TRUE, FALSE, TRUE))){
return(x[2])
} else {
return(NA)
}
})
foo$val_clean <- val[c(-1, -length(val))] # Remove first and last values
foo$val_clean
ggplot(foo) + geom_line(aes(time, value)) + geom_point(aes(time, val_clean))
我正在使用 ggplot2
和 geom_line()
制作大量时间序列的线图。数据集有大量的缺失值,我很高兴没有在缺失的部分画线,因为这看起来很尴尬。
我的问题是未绘制被 NA 包围的单个非 NA 数据点(或序列 beginning/end 的点,另一侧为 NA)。一个潜在的解决方案是为所有观察添加 geom_point()
,但这会使我的文件大小增加十倍,并使情节更难阅读。
因此,我只想识别那些未显示 geom_line()
的数据点,并仅为那些 添加点。有没有直接的方法来识别这些点?
我的数据目前是长格式的,下面的MWE可以作为说明。我想识别第 1 行和第 7 行,以便绘制它们:
library(ggplot2)
set.seed(1)
dat <- data.frame(time=rep(1:5,2),country=rep(1:2,each=5),value=rnorm(10))
dat[c(2,6,8),3] <- NA
ggplot(dat) + geom_line(aes(time,value,group=country))
> dat
time country value
1 1 1 -0.6264538
2 2 1 NA
3 3 1 -0.8356286
4 4 1 1.5952808
5 5 1 0.3295078
6 1 2 NA
7 2 2 0.4874291
8 3 2 NA
9 4 2 0.5757814
10 5 2 -0.3053884
你的意思是这样的吗?
library(tidyverse)
dat %>%
na.omit() %>%
ggplot() +
geom_line(aes(time, value, group = country))
您可以使用 zoo::rollapply
函数创建一个新列,其值仅以 NA 结尾。然后你可以简单地绘制这些点。例如:
library(zoo)
library(ggplot2)
foo <- data.frame(time =c(1:11), value = c(1 ,NA, 3, 4, 5, NA, 2, NA, 4, 5, NA))
# Perform sliding window processing
val <- c(NA, NA, foo$value, NA, NA) # Add NA at the ends of vector
val <- rollapply(val, width = 3, FUN = function(x){
if (all(is.na(x) == c(TRUE, FALSE, TRUE))){
return(x[2])
} else {
return(NA)
}
})
foo$val_clean <- val[c(-1, -length(val))] # Remove first and last values
foo$val_clean
ggplot(foo) + geom_line(aes(time, value)) + geom_point(aes(time, val_clean))