我有一個名為的資料集df1,如下所示:
category subject runtime
foo square 7.3
foo circle. 10.5
foo2 square 15.3
...
還有一個名為 的第二個子集df2,我在其中過濾categoryn > 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")
結果與上述相同。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/414677.html
標籤:
