我有一个名为的资料集df1
,如下所示:
category subject runtime
foo square 7.3
foo circle. 10.5
foo2 square 15.3
...
还有一个名为 的第二个子集df2
,我在其中过滤category
n > 1 的位置,这会导致较小的资料帧category==foo2
被洗掉:
category subject runtime
foo square 7.3
foo circle. 10.5
...
我尝试在一个函式中绘制这两个资料集,该函式将创建一个箱线图(对于所有出现多次 的行category
,因此我在df2
这里使用geom_boxplot
子集和点图来表示只有一次出现的category
。例如:
create.my.plot <- function(df, df.subset, xaxis, yaxis, xlab, ylab) {
ex.plot <- ggplot(df, aes(x=xaxis, y=yaxis))
geom_boxplot(data = df.subset, aes(fill=xaxis))
geom_point(position="identity", size=1)
labs(x=xlab, y=ylab)
ex.plot
}
我可以在这个绘图函式之外很好地创建这个图,但是当我从这个函式呼叫它时,它回传一个关于资料帧长度的错误:
> create.my.plot(df1, df2, df$category, df$runtime, "Category", "Runtime")
Error: Aesthetics must be either length 1 or the same as the data (3): x and y
我想这是因为当ggplot()
被呼叫时,它与df
并期望变量在?aes()
中具有行数df
?
我更喜欢使用绘图功能,因为我必须重复创建绘图但是如何克服这个错误,我需要使用不等长度的不同资料集来绘制图层?
uj5u.com热心网友回复:
问题是您用来df$...
将要绘制的变量传递给您的函式。你得到的错误是为什么作为一般规则你永远不应该使用df$...
inside的原因之一aes()
。
而是将您的列作为不带引号的名称传递给函式,并在内部使用{{
(= curly-curly) aes()
:
library(ggplot2)
create.my.plot <- function(df, df.subset, xaxis, yaxis, xlab, ylab) {
ggplot(df, aes(x = {{ xaxis }}, y = {{ yaxis }}))
geom_boxplot(data = df.subset, aes(fill = {{ xaxis }}))
geom_point(position = "identity", size = 1)
labs(x = xlab, y = ylab)
}
create.my.plot(df1, df2, category, runtime, "x", "y")
或者作为第二个选项,将列名作为带引号的字符串传递并使用.data
代词:
create.my.plot1 <- function(df, df.subset, xaxis, yaxis, xlab, ylab) {
ggplot(df, aes(x = .data[[xaxis]], y = .data[[yaxis]]))
geom_boxplot(data = df.subset, aes(fill = .data[[xaxis]]))
geom_point(position = "identity", size = 1)
labs(x = xlab, y = ylab)
}
create.my.plot1(df1, df2, "category", "runtime", "x", "y")
资料
df1 <- data.frame(
category = c("foo", "foo", "foo2"),
subject = c("square", "circle", "square"),
runtime = 1:3
)
df2 <- df1[df1$category != "foo2", ]
uj5u.com热心网友回复:
Stefan 的回答很好,但会绘制与箱线图相关的所有点。我会建议这样做(我使资料更加真实)。首先,资料如下:
df1 <- data.frame(
category = factor(rep(c("foo", "foo3", "foo2"), c(100,100, 1))),
subject = sample(c("circle", "square"), 201, replace=TRUE),
runtime = runif(201, 5, 25)
)
接下来,在您的资料中创建一个新变量来计算每组的观察次数。
df1 <- df1 %>%
group_by(category) %>%
mutate(n = n())
将资料过滤为将用点绘制的资料和用方框绘制的资料:
df_pt <- df1 %>%
filter(n == 1)
df_box <- df1 %>%
filter(n > 1)
然后,可以修改该函式以使用点和框资料集。重要的是点资料集将包含所有点
create.my.plot1 <- function(df.point, df.box, xaxis, yaxis, xlab, ylab) {
ggplot()
geom_point(data=df.point, aes_string(x = xaxis, y = yaxis),
position = "identity", size = 1)
geom_boxplot(data = df.box, aes_string(x=xaxis, y=yaxis, fill = xaxis))
labs(x = xlab, y = ylab)
}
最后,在您的资料上呼叫绘图:
create.my.plot1(df_pt, df_box, "category", "runtime", "x", "y")
或者,您也可以构建函式来为您完成所有子集作业:
df1 <- data.frame(
category = factor(rep(c("foo", "foo3", "foo2"), c(100,100, 1))),
subject = sample(c("circle", "square"), 201, replace=TRUE),
runtime = runif(201, 5, 25)
)
create.my.plot1 <- function(dat, xaxis, yaxis, xlab, ylab) {
x <- dat %>%
group_by(across(all_of(xaxis))) %>%
mutate(n = n())
pt <- x %>% filter(n == 1)
box <- x %>% filter(n > 1)
cat("Number of sinlge points: ", nrow(pt), "\nNumber of boxes: ", length(table(box[[xaxis]])), "\n")
ggplot()
geom_point(data=pt, aes_string(x = xaxis, y = yaxis),
position = "identity", size = 1)
geom_boxplot(data = box, aes_string(x=xaxis, y=yaxis, fill = xaxis))
labs(x = xlab, y = ylab)
}
create.my.plot1(df1, "category", "runtime", "x", "y")
结果与上述相同。
0 评论