【问题标题】:How to loop through columns in R to create plots?如何遍历 R 中的列来创建绘图?
【发布时间】:2021-11-17 21:53:24
【问题描述】:

我的数据框中包含三列:年龄、性别和收入。

我想遍历这些列并根据其中的数据创建图表。

我知道在 stata 中您可以遍历变量,然后使用这些变量运行命令。但是下面的代码似乎不起作用,是否有等效的方法可以在 R 中做我想做的事情?

groups <- c(df$age, df$gender, df$income) 
for (i in groups){   
df %>% group_by(i) %>%
    summarise(n = n()) %>%
    mutate(prop = n/sum(n)) %>%
    ggplot(aes(y = prop, x = i)) +
    geom_col()  
}

【问题讨论】:

    标签: r loops ggplot2


    【解决方案1】:

    您也可以使用 tidyverse。循环使用 map 分组变量名称的向量。在每次迭代中,您可以将变量名 !!sym(variable) 评估为 group_by。或者,我们可以使用across(all_of()),它可以直接将字符串作为列名。其余代码与您使用的代码几乎相同。

    library(dplyr)
    library(purrr)
    
    groups <- c('age', 'gender', 'income') 
    
    ## with    !!(sym(.x))
    
    map(groups, ~ 
        df %>% group_by(!!sym(.x)) %>%
        summarise(n = n()) %>%
        mutate(prop = n/sum(n)) %>%
        ggplot(aes(y = prop, x = i)) +
        geom_col()
       )
    
    ## with    across(all_of())
    
    map(groups, ~ 
        df %>% group_by(across(all_of(.x))) %>%
        summarise(n = n()) %>%
        mutate(prop = n/sum(n)) %>%
        ggplot(aes(y = prop, x = i)) +
        geom_col()
       )
    
    

    如果你想使用 for 循环:

    groups <- c('age', 'gender', 'income')
    
    for (i in groups){   
    df %>% group_by(!!sym(i))) %>%
        summarise(n = n()) %>%
        mutate(prop = n/sum(n)) %>%
        ggplot(aes(y = prop, x = i)) +
        geom_col()  
    }
    

    【讨论】:

    • 波浪号是 purrr 和其他 tydiverse 包(如 dplyr)中 lambda/匿名函数的缩写形式。它使编写 lambda 函数更容易一些。然后function(x) x 可以简化为~ .x。在上面的答案中,波浪号可以替换为function (.x)
    • 双重 bang sin !! 来自 rlang 包(也用于 dplyr)。 “groups”变量是一个字符串。当您使用 sym() 将其转换为符号时,它将成为一个符号(名称-对象对应键)。然后双 bang 符号 (!!) 评估该符号,从而为我们提供所需的列。如果您将列名直接用作字符串,它将不起作用,因为它尚未与数据框中的任何对象关联。 group_by() 不直接接受列名。您必须转换为符号并进行评估。
    • 这也可以使用其他 dplyr 函数来完成,例如 select() 和 mutate() 或 cross(),使用 !!(sym(x)) 或使用直接将字符串作为列名,例如all_of()if_all
    • 我在across(all_of)) 中包含了一个答案版本。对于初学者来说,它比 !!(sym(.x)) 更清楚,并且几乎相同。
    • 在这种情况下,您正在寻找对象 .x 作为字符串的实际值,因此您不必转换为符号,只需使用 `ggsave( paste0("results/JS05 -调查/", .x, ".png")
    【解决方案2】:

    您可以使用lapply

    df <- data.frame(age = sample(c("26-30", "31-35", "36-40", "41-45"), 20, replace = T),
                     gender = sample(c("M", "F"), 20, replace = T),
                     income = sample(c("High", "Medium", "Low"), 20, replace = T),
                     prop   = runif(20))
    
    lapply(df[,c(1:3)], function(x) ggplot(data = df, aes(y = df$prop, x = x))+ geom_col())
    

    【讨论】:

    • 非常感谢,如果我不知道列号,我可以在 lapply 中按名称引用它们吗?
    • @entropy 是的,你可以。
    猜你喜欢
    • 2020-04-06
    • 2018-12-15
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2014-12-05
    • 2013-03-04
    相关资源
    最近更新 更多