首页 > 解决方案 > 如何在 for 循环中进行可视化

问题描述

我想创建一个函数来创建跨多个维度和数字变量的直方图。

我正在尝试这样做,除了 x 轴采用最终循环的值。因此,当最终循环的 x 轴从 0 扩展到 5000 时,无论如何,所有直方图都将具有相同的 x 轴。

这是我的代码

  groups_df <- 
    data.frame(
      groups = 
          c(rep("ABC", 3),
          rep("XYZ", 2)),
      cuts = 
          c(c("cat", "dog", "bird"), 
            c("red", "blue")) %>%
    mutate(groups = as.character(groups),
           cuts = as.character(cuts))
  
  numeric.variables <-
    c("hops",
      "skips",
      "jumps")
    
  visualizations <- list()
  
  for (i in seq_along(groups_df$groups)){

    for (j in seq_along(numeric.variables)){

      visualizations[[groups_df$groups[i]]][[str_replace_all(tolower(groups_df$cuts[i]), " ", "_")]][[numeric.variables[j]]] <-
        mydf %>% 
        filter(get(groups_df$groups[i]) == list.of.groups_df$cuts[i]) %>% 
        ggplot(aes(get(numeric.variables[j]))) +
        geom_histogram() + 
        labs(x = numeric.variables[j],
             title = paste0(str_replace_all(numeric.variables[j], "_", " "), " - ", tolower(groups_df$cuts[i])))
        
    }
  }
  

标签: r

解决方案


该错误来自 for 循环内的惰性求值。因此,您的 ggplot 仅在最后一次调用时进行评估。

根据我的猜测,您想根据 2 个类别(或更多)中的值来划分数值。如果您想将它们列在列表中,这是一种方法:

mydf = data.frame(cat_1 = sample(letters[1:3],500,replace=TRUE),
                  cat_2 = sample(letters[4:5],500,replace=TRUE),
                  var_1 = rnorm(500),
                  var_2 = rnorm(500)
)

# categorical columns
cat_columns = c("cat_1","cat_2")
# numeric variables
num_columns = c("var_1","var_2")
 
plts = lapply(cat_columns,function(col_){
  #iterate categories of that column
  p2 = lapply(unique(mydf[, col_]), function(cut_){
    #iterate values
    p3 = lapply(num_columns, function(var_){
      thisdf = data.frame(x = mydf[mydf[, col_] == cut_, var_])
      return(ggplot(thisdf, aes(x = x)) + geom_histogram())
      
    })
    names(p3) = num_columns
    return(p3)
  })
  names(p2) =  unique(mydf[, col_])
  return(p2)
  
})

names(plts) = cat_columns

plts[["cat_1"]][["a"]][["var_1"]]

在此处输入图像描述

更好的方法,实际上是旋转两次并嵌套它们,并且代码更少:

mydf %>% 
  pivot_longer(-c(var_1,var_2), names_to = "cat", values_to = "cut") %>% 
  pivot_longer(-c(cat,cut), names_to = "num") %>% 
  nest(data = c(value))

# A tibble: 10 x 4
   cat   cut   num   data              
   <chr> <fct> <chr> <list>            
 1 cat_1 a     var_1 <tibble [145 x 1]>
 2 cat_1 a     var_2 <tibble [145 x 1]>
 3 cat_2 d     var_1 <tibble [257 x 1]>
 4 cat_2 d     var_2 <tibble [257 x 1]>
 5 cat_1 c     var_1 <tibble [173 x 1]>
 6 cat_1 c     var_2 <tibble [173 x 1]>
 7 cat_2 e     var_1 <tibble [243 x 1]>
 8 cat_2 e     var_2 <tibble [243 x 1]>
 9 cat_1 b     var_1 <tibble [182 x 1]>
10 cat_1 b     var_2 <tibble [182 x 1]>

然后我们可以使用 lapply 来存储图,如果您的数据不是那么大:

plts = mydf %>% 
  pivot_longer(-c(var_1,var_2), names_to = "cat", values_to = "cut") %>% 
  pivot_longer(-c(cat,cut), names_to = "num") %>% 
  nest(data = c(value)) %>%
  mutate(plots = lapply(data, function(i) qplot(i$value)))


plts %>% filter(cat=="cat_1" & num=="var_1" & cut=="a") %>% pull(plots)

在此处输入图像描述


推荐阅读