【问题标题】:R - Applying same function on multiple columnsR - 在多列上应用相同的功能
【发布时间】:2019-10-23 15:40:11
【问题描述】:

这是我第一次在这里提问,我是 R 的初学者。

我有一个庞大的数据集,我想根据类别对多列的值进行一些概述:

sampleID|category|element_1|element_2|element_3|element_4|
----------------------------------------------------------
    1   |    A   |  12.53  |   46.17 |   94.09 |  25.23  |
    2   |    B   |  19.53  |   16.17 |   14.09 |  28.23  |
    3   |    C   |  21.53  |   56.17 |   24.09 |  26.23  |
    4   |    D   |  18.53  |   96.17 |   34.09 |  21.23  |
    5   |    B   |  17.53  |   76.17 |   44.09 |  24.23  |
    6   |    A   |  32.53  |   36.17 |   54.09 |  25.23  |

我一直在尝试按每个类别获取每个元素的平均值,我一直在尝试的主要是 R 中的 tapply 函数:

tapply(data$element1, data$category, mean)

这为一个元素列提供了很好的结果,但我似乎无法找到如何在所有列上执行此操作的答案,而无需手动对每一列元素进行操作(element1、element2、element3 等的平均值)类别)。

我想要的是这个:

category | element_1| element_2| element_3 
     A   |   mean   |   mean   |   mean
     B   |   mean   |   mean   |   mean
     C   |   mean   |   mean   |   mean

我尝试了applyaggregate 的版本,但无法正常工作。

感谢任何建议,如果我需要提供更多信息,请告诉我!

【问题讨论】:

  • 你能分享你的数据样本和你想要的输出吗?我只是想确定您在寻找什么!

标签: r dataframe statistics tapply


【解决方案1】:

如果您只想聚合列,可以使用 dplyr 库。

library(dplyr)
df = data.frame(sample_id = c(1,2,3,4),
                category = c("A", "B", "C", "A"),
                element1 = c(1,2,3,4),
                element2 = c(5,6,7,8),
                element3 = c(9,10,11,12))

summarise_if(df, is.numeric, mean)

或同等的

df %>% summarise_if(is.numeric, mean)

这会将函数均值应用于每一个数字列。

【讨论】:

    【解决方案2】:

    如果您想了解更多信息,而不仅仅是平均值,您可以查看汇总统计信息。

    让我们创建一些示例数据:

    library(tidyverse)
    set.seed(1)
    
    my_data <- as_tibble(matrix(runif(100), ncol = 10,
                                dimnames = list(rows = NULL,
                                                cols = paste0("Var_", 1:10))))
    
    

    现在,我们只需使用 summary 即可查看完整的汇总统计信息:

    summary(my_data)
    
    # Alternatively 
    my_data %>%
      summary
    
    

    您可以使用基础(或Rfast 包中的matrixStats)中的colMeans 函数。

    my_data %>%
      colMeans
    

    如果您只想对数据的子集执行此操作,则可以使用 select 函数

    my_data %>%
      select(Var_1, Var_2) %>%
      colMeans
    

    请注意,当您使用colMeans 时,如果没有先选择仅数字变量,则会引发错误。 summary 仍然可以正常工作。

    编辑:

    考虑您的评论并重新阅读您的(更新的)问题,这可能更接近您正在寻找的内容。

    library(tidyverse)
    
    set.seed(1)
    
    data <- tibble(
      sampleID = 1:6,
      category = c("A", "B", "C", "D", "B", "A"),
      element_1 = runif(6)*10,
      element_2 = runif(6)*10,
      element_3 = runif(6)*10,
      element_4 = runif(6)*10
      )
    

    这给出了一个如下所示的数据集:

    # A tibble: 6 x 6
      sampleID category element_1 element_2 element_3 element_4
         <int> <chr>        <dbl>     <dbl>     <dbl>     <dbl>
    1        1 A             4.97     7.80       2.52      5.06
    2        2 B             9.93     7.62       4.23      7.16
    3        3 C             3.77     6.16       2.02      1.51
    4        4 D             4.78     0.510      5.02      4.79
    5        5 B             1.67     6.96       3.14      2.58
    6        6 A             6.07     9.76       9.99      6.47
    

    现在,我们只需稍作改动,使用group_by() 函数

    data %>%
      group_by(category) %>%
      summarize_if(is.numeric, mean)
    

    这将提供所需的输出:

      category sampleID element_1 element_2 element_3 element_4
      <chr>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
    1 A             3.5      5.52     8.78       6.26      5.77
    2 B             3.5      5.80     7.29       3.69      4.87
    3 C             3        3.77     6.16       2.02      1.51
    4 D             4        4.78     0.510      5.02      4.79
    

    【讨论】:

    • 获取摘要和平均值很好,我之前对每一列都这样做了!问题是根据列类别的值获取列平均值:即类别 A、类别 B 和类别 C 中 element_1 的平均值!这就是我尝试使用 tapply 的原因,但它当时只适用于一列(不能同时对 element_1-element_n 执行此操作)。
    • 你是对的。我又看了你的问题并编辑了答案。我把原来的答案留在那里,但 EDIT: 之后的一切都应该是你要找的。如果没有,请告诉我我在哪里误解了你。
    • 谢谢!这正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2014-03-27
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多