如何在 R 中围绕 NA 值绘制多边形?
How to draw a polygon around NA values in R?
我正在尝试使用基础图形在我的数据周围绘制一个错误区域。我已经想出如何用多边形来做,但如果我的数据中有任何 NA
值,它就会开始表现得很糟糕。
dat <- rnorm(10, mean = 1:10)
depth <- 11:20
sd <- rnorm(10, mean = 1.5, sd = 0.5)
col <- "blue"
alpha <- .2
col <- adjustcolor(col, alpha.f = alpha)
par(mfrow = c(1,2))
plot(dat, depth, type = "o", main = "No NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
dat[7] <- NA
plot(dat, depth, type = "o", main = "NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
这给了我下面的图像:
似乎 NA 值将下多边形分成两个多边形。我希望它做的是将其保留为一个多边形。
这是使用 rle
函数的可能解决方案:
set.seed(123) # added for reproducibility
dat <- rnorm(10, mean = 1:10)
depth <- 11:20
sd <- rnorm(10, mean = 1.5, sd = 0.5)
col <- "blue"
alpha <- .2
col <- adjustcolor(col, alpha.f = alpha)
par(mfrow = c(1,2))
plot(dat, depth, type = "o", main = "No NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
dat[7] <- NA
plot(dat, depth, type = "o", main = "NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
############################################
## code to print error range starts here: ##
############################################
enc <- rle(!is.na(dat))
endIdxs <- cumsum(enc$lengths)
for(i in 1:length(enc$lengths)){
if(enc$values[i]){
endIdx <- endIdxs[i]
startIdx <- endIdx - enc$lengths[i] + 1
subdat <- dat[startIdx:endIdx]
subsd <- sd[startIdx:endIdx]
subdepth <- depth[startIdx:endIdx]
x <- c(subdat - subsd, rev(subdat + subsd))
y <- c(subdepth, rev(subdepth))
polygon(x = x, y = y, col = col, border = NA)
}
}
想法是为每个连续的非 NA 块绘制一个多边形。
由于rle
,给定一个向量,returns具有相同值的连续块的长度和值,我们用它来识别不 NA 的块并绘制多边形对原始 dat
、depth
和 sd
向量进行子集化。
这可以接受吗?
polygon(x = x[!is.na(x)], y = y[!is.na(x)], col = col, border = NA)
如果您想尝试 ggplot2
解决方案,请看这里:
将示例数据放入数据框中并添加低和高列(将一个数据点设置为 NA
后):
> d=data.frame(dat=dat, depth=depth)
> d$dat[7]=NA
> d$high=d$dat+sd
> d$low=d$dat-sd
然后是单行:
> require(ggplot2)
> ggplot(d,aes(x=depth,y=dat)) +
geom_ribbon(aes(ymax=high,ymin=low),
fill=adjustcolor("blue",.2) ) +
geom_line() +
geom_point() +
coord_flip()
我正在尝试使用基础图形在我的数据周围绘制一个错误区域。我已经想出如何用多边形来做,但如果我的数据中有任何 NA
值,它就会开始表现得很糟糕。
dat <- rnorm(10, mean = 1:10)
depth <- 11:20
sd <- rnorm(10, mean = 1.5, sd = 0.5)
col <- "blue"
alpha <- .2
col <- adjustcolor(col, alpha.f = alpha)
par(mfrow = c(1,2))
plot(dat, depth, type = "o", main = "No NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
dat[7] <- NA
plot(dat, depth, type = "o", main = "NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
这给了我下面的图像:
似乎 NA 值将下多边形分成两个多边形。我希望它做的是将其保留为一个多边形。
这是使用 rle
函数的可能解决方案:
set.seed(123) # added for reproducibility
dat <- rnorm(10, mean = 1:10)
depth <- 11:20
sd <- rnorm(10, mean = 1.5, sd = 0.5)
col <- "blue"
alpha <- .2
col <- adjustcolor(col, alpha.f = alpha)
par(mfrow = c(1,2))
plot(dat, depth, type = "o", main = "No NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
polygon(x = x, y = y, col = col, border = NA)
dat[7] <- NA
plot(dat, depth, type = "o", main = "NAs in dat or depth")
x <- c(dat - sd, rev(dat + sd))
y <- c(depth, rev(depth))
############################################
## code to print error range starts here: ##
############################################
enc <- rle(!is.na(dat))
endIdxs <- cumsum(enc$lengths)
for(i in 1:length(enc$lengths)){
if(enc$values[i]){
endIdx <- endIdxs[i]
startIdx <- endIdx - enc$lengths[i] + 1
subdat <- dat[startIdx:endIdx]
subsd <- sd[startIdx:endIdx]
subdepth <- depth[startIdx:endIdx]
x <- c(subdat - subsd, rev(subdat + subsd))
y <- c(subdepth, rev(subdepth))
polygon(x = x, y = y, col = col, border = NA)
}
}
想法是为每个连续的非 NA 块绘制一个多边形。
由于rle
,给定一个向量,returns具有相同值的连续块的长度和值,我们用它来识别不 NA 的块并绘制多边形对原始 dat
、depth
和 sd
向量进行子集化。
这可以接受吗?
polygon(x = x[!is.na(x)], y = y[!is.na(x)], col = col, border = NA)
如果您想尝试 ggplot2
解决方案,请看这里:
将示例数据放入数据框中并添加低和高列(将一个数据点设置为 NA
后):
> d=data.frame(dat=dat, depth=depth)
> d$dat[7]=NA
> d$high=d$dat+sd
> d$low=d$dat-sd
然后是单行:
> require(ggplot2)
> ggplot(d,aes(x=depth,y=dat)) +
geom_ribbon(aes(ymax=high,ymin=low),
fill=adjustcolor("blue",.2) ) +
geom_line() +
geom_point() +
coord_flip()