【问题标题】:How to make visualizations in a for loop如何在 for 循环中进行可视化
【发布时间】:2020-09-29 13:15:44
【问题描述】:

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

我正在尝试这样做,除了 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])))
        
    }
  }
  

【问题讨论】:

  • mydf 是哪里或什么?
  • 嗨@Cauder,这是R中的惰性评估。请参阅stackoverflow.com/questions/41666078/…..尝试将它们放在一个方面或使用lapply
  • 它可以是任何东西。我们可以将其称为泰坦尼克号数据集,并将组和剪辑更新为 groups= c("Gender", "Class) and cuts = c(c("Male", Female), c("First, "Second" "Third ")
  • @StupidWolf,即使分配给列表也是如此吗?能否请您用 lapply 写一个答案,以便我将其标记为正确
  • @Cauder,没关系..也许你用我发布的链接中的 lapply 试试?否则我会将这个问题标记为重复。

标签: r


【解决方案1】:

错误来自 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)

【讨论】:

  • 这个答案很好,请接受这个赏金
  • 嗨@Cauder,还有其他问题吗? It's giving me plts[[1]]$cat_1$var1 and I want it to be plts$cat_1$var1 如果我运行我的解决方案,我不明白
猜你喜欢
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多