Name Value1 Value2 Value3
1 A1 -0.05970872 -1.1651404 1.3516952
2 A2 0.44143488 -0.7270722 -1.9870423
3 A3 0.34616897 -0.3891095 0.9123736
4 A4 0.49289331 1.3957877 -0.2689896
5 A5 -1.39354557 0.9429327 1.0719274
我有上面的数据框,我想在 ggplot2 中为其生成四个图表,每个图表的 x 轴作为“名称”列,y 轴作为其他列的值。虽然 x 轴不需要有“刻度线”,但如果 y 轴低于截止值(例如 0),我确实想有条件地使用相应“名称”列值的名称来标记这些点。下面是我的代码使用 R 中的基本绘图函数通过循环函数自动生成图形。我附上了一张示例图。
cutoff = 0
df = read.csv("Book4.csv", header = TRUE)
list = rownames(df)
for(i in names(df)){
png(filename = paste(i,".png"))
plot(df[,i],
main = i,
ylab = "Values",
xlab = "Names",
col = ifelse(df[,i]<cutoff, 'red', 'gray'),
pch = ifelse(df[,i] < cutoff, 10, 1)
)
abline(cutoff, 0, col= "blue", lty=2)
outlier = which(df[,i]<=cutoff)
if (length(outlier)>0){
text(outlier, df[outlier,i], list[outlier], cex=0.7, pos=2)
}
dev.off()
}
问题是这些图形标签通常是隐藏的,或者当我使用较大的数据集时重叠,因此我无法读取它们。因此,我想使用 ggplot2 和函数 geom_text_repel 重现这一点。我尝试使用 for 循环来执行此操作,但在使用 geom_text_repel 点标记的实现中陷入困境,因为我不确定如何有条件地使用它进行标记。我将生成超过 200 个 png,因此如果它可以自动化并以“Value1.png”、“Value2.png”等文件名输出,我将不胜感激。
这是我在下面的 ggplot 中的尝试
cutoff = 0
df = read.csv("Book4.csv", header = TRUE, row.names = 1)
for(i in colnames(df)){
png(filename = paste(i,".png"))
outlier = which(df[,i]<=cutoff)
print(ggplot(df, aes(x = rownames(df), y = df[,i])) +
geom_point() +
geom_text_repel(data = df, label=outlier))
dev.off()
}
我不断收到错误“错误:美学必须是长度 1 或与数据 (5): 标签相同”,并且不确定如何解决该问题。
最佳答案
你可以像这样达到你想要的结果:
使用
df[,i]
时在大多数情况下会起作用,但不推荐,并且确实在某些情况下它不起作用。相反,如果您想通过字符串引用变量,您可以使用所谓的.data
代词,即使用.data[[i]]
.要获取条件标签,您可以映射
ifelse(.data[[i]] <= cutoff, Name, "")
关于label
内在美学aes()
(!!)。
library(ggplot2)
library(ggrepel)
cutoff <- 0
for (i in colnames(df)) {
png(filename = paste(i, ".png"))
gg <- ggplot(df, aes(x = rownames(df), y = .data[[i]])) +
geom_point() +
geom_text_repel(aes(label = ifelse(.data[[i]] <= cutoff, Name, "")))
print(gg)
dev.off()
}
编辑首先。如果您想使用过滤器,最好将行名作为新变量添加到数据集中,例如使用df$x <- rownames(x)
,可以映射到 x
(我猜这就是您收到错误消息的原因)。之后您可以使用data = dplyr::filter(df, .data[[i]] <= cutoff)
作为数据集。
注意 不过,有一点需要注意。如果您想添加另一个geom_point
,这种方法就很好。仅包含您的数据的子集。如果是geom_text_repel
但是不建议这样做(这就是我使用 ifelse
的原因)。原因是,geom_text_repel
只有了解全部数据才能做好工作。如果仅传递一个子集,则标签通常会与子集数据中缺失的点重叠,如 geom_text_repel
不知道这些在那里。
df$x <- row.names(df)
for (i in colnames(df)) {
png(filename = paste(i, ".png"))
gg <- ggplot(df, aes(x = x, y = .data[[i]])) +
geom_point() +
geom_text_repel(data = dplyr::filter(df, .data[[i]] <= cutoff), aes(x = x, y = .data[[i]], label = Name))
print(gg)
dev.off()
}
数据
df <- structure(list(Name = c("A1", "A2", "A3", "A4", "A5"), Value1 = c(
-0.05970872,
0.44143488, 0.34616897, 0.49289331, -1.39354557
), Value2 = c(
-1.1651404,
-0.7270722, -0.3891095, 1.3957877, 0.9429327
), Value3 = c(
1.3516952,
-1.9870423, 0.9123736, -0.2689896, 1.0719274
)), class = "data.frame", row.names = c(
"1",
"2", "3", "4", "5"
))
关于r - 如何使用条件标签在循环中制作多个ggplots,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64343500/