【问题标题】:ggplot subset a list within a functionggplot子集一个函数内的列表
【发布时间】:2020-12-15 03:20:12
【问题描述】:

我有一个解决方案来格式化嵌套的分面标签,效果非常好。解决方案由here 提供。

我需要提出另一个问题,因为我需要能够对列表进行子集化,但显然我无法在没有帮助的情况下弄清楚!

我需要做的: 我希望能够从列表中排除 Fac2。所以图表将只显示 Fac1 和 Fac3。我想我需要对这个列表进行子集List <- split(data,data$Fac_Map)

  • 在实际数据中,它是一个很长的 Fac 列表和一个宽图表,所以我想排除而不是列出所有包含的内容。
  • 我将把 Fac2 放在由 ggarrange 连接的图表的末尾(这有两个原因,但无需深入了解真实数据的复杂性)。所以我需要能够过滤第一个函数 G 中的列表。

数据:

data <- structure(
  list(
    Fac_Map = structure(
      c(1L, 1L, 1L, 1L, 2L, 2L,
        2L, 2L, 3L, 3L, 3L, 3L),
      .Label = c("Fac1", "Fac2", "Fac3"),
      class = "factor"
    ),
    S_Residency = structure(
      c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L,
        1L, 1L, 2L, 2L),
      .Label = c("Intl", "Local"),
      class = "factor"
    ),
    Period = structure(
      c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L,
        2L, 1L, 2L),
      .Label = c("2019 P2", "2020 P2"),
      class = "factor"
    ),
    Result = c(92.9, 91.1, 85.8, 87.9, 94.1, 91.7, 87.5, 88.6,
               90, 90.1, 87.4, 88.9)
  ),
  class = "data.frame",
  row.names = c(NA,-12L)
)

格式化由@Duck here提供的分面标签的工作解决方案

#Create list
List <- split(data,data$Fac_Map)
#Now function to plot
myplotfun <- function(x)
{
  G <- ggplot(x,aes(x=Period,y=Result))+
    geom_point() +
    facet_grid(. ~ S_Residency,
               scales = "free", space = "free") +
    ylim(range(x$Result)) +
    xlab("")+ylab("")+ggtitle(unique(x$Fac_Map))
  return(G)
}
#Apply for plots
List2 <- lapply(List,myplotfun)
#Wrap final plot
wrap_plots(List2,nrow = 1)

是否可以过滤列表,这样我就可以只拥有 Fac1 和 Fac3 而不必对整个数据集进行子集化,这会阻止 ggarrange?

代码的输出:

【问题讨论】:

  • 也许我没有完全理解这个问题,但是wrap_plots(List2[-2],nrow = 1) 有什么问题?
  • 感谢@teunbrand,这可能会有所帮助。我无法弄清楚如何将字符串“Fac2”传递给这个,这可以通过某种方式完成吗?我需要传入一个字符串,因为图形可以根据用户选择动态变化。
  • 如果您想依赖字符匹配而不是已知位置,您可以执行以下操作:rm_me &lt;- match("Fac2", names(List2)); wrap_plots(List2[-rm_me],nrow = 1)

标签: r list ggplot2


【解决方案1】:

我会建议两种方法来解决您的问题。您可以使用 $ 删除元素或定义一个带有要删除名称的向量。这里的代码使用你的数据框data

我们有两种方法来移除对象。首先,我们可以使用$ 并调用元素以删除:

library(ggplot2)
library(dplyr)
library(patchwork)
#Create list
List <- split(data,data$Fac_Map)
#Remove
List$Fac2 <- NULL
#Plot
#Now function to plot
myplotfun <- function(x)
{
  G <- ggplot(x,aes(x=Period,y=Result))+
    geom_point() +
    facet_grid(. ~ S_Residency,
               scales = "free", space = "free") +
    ylim(range(x$Result)) +
    xlab("")+ylab("")+ggtitle(unique(x$Fac_Map))
  return(G)
}
#Apply for plots
List2 <- lapply(List,myplotfun)
#Wrap final plot
wrap_plots(List2,nrow = 1)

输出:

第二种方法,我们可以设置要删除的名称向量并使用索引:

List <- split(data,data$Fac_Map)
#Define vector with names
vecrem <- c("Fac2")
#Remove
List[[vecrem]] <- NULL
#Now function to plot
myplotfun <- function(x)
{
  G <- ggplot(x,aes(x=Period,y=Result))+
    geom_point() +
    facet_grid(. ~ S_Residency,
               scales = "free", space = "free") +
    ylim(range(x$Result)) +
    xlab("")+ylab("")+ggtitle(unique(x$Fac_Map))
  return(G)
}
#Apply for plots
List2 <- lapply(List,myplotfun)
#Wrap final plot
wrap_plots(List2,nrow = 1)

输出:

更新:

您可以通过在新列表中隔离所需元素并从大列表中删除以继续绘图方案来获得单独的绘图。然后您以正常方式应用该功能,最后您可以保存在新对象G1G2 中。最后,您可以根据需要合并或排列:

#Create list
List <- split(data,data$Fac_Map)
#Define vector with names
vecrem <- c("Fac2")
#Isolate in a new list
List.single <- List[vecrem]
#Remove from big list
List[[vecrem]] <- NULL
#Now function to plot
myplotfun <- function(x)
{
  G <- ggplot(x,aes(x=Period,y=Result))+
    geom_point() +
    facet_grid(. ~ S_Residency,
               scales = "free", space = "free") +
    ylim(range(x$Result)) +
    xlab("")+ylab("")+ggtitle(unique(x$Fac_Map))
  return(G)
}
#Apply for plots
List2 <- lapply(List,myplotfun)
#Apply the plot for single element
List.single2 <- lapply(List.single,myplotfun)
#Wrap final plot
G1 <- wrap_plots(List2,nrow = 1)
G2 <- wrap_plots(List.single2,nrow = 1)
#Merge plots
G1+G2

输出G1:

输出G2:

合并输出G1+G2:

【讨论】:

  • 这正是我需要的@Duck 非常非常感谢。我很快就会接受这个。既然我知道如何从列表中过滤掉某些东西(您的两个解决方案都可以正常工作) - 还有一种方法可以做相反的事情,就像过滤列表以仅显示 Fac2?也不知道该怎么做:(我需要能够在最后添加 Fac2 图。
  • @Keelin 你的意思是只有 Fac2 的情节吗?
  • 是的,这就是我的意思,我将使用 ggarrange 将其添加为第二个图(它在真实数据中具有不同的周期)
  • @Keelin 我已经为你添加了一个更新,它可以满足你的需求 :)
【解决方案2】:

您可以在拆分前过滤数据并删除未出现在数据中的级别:

data <- data %>% 
  filter(Fac_Map != "Fac2")  %>% 
  mutate(Fac_Map = fct_drop(Fac_Map))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多