【问题标题】:Sum rows in data.frame or matrix对 data.frame 或矩阵中的行求和
【发布时间】:2011-04-28 20:38:43
【问题描述】:

我有一个非常大的数据框,其中行作为观察值,列作为遗传标记。我想创建一个新列,其中包含使用 R 为每个观察值选择的列的总和。

如果我有 200 列和 100 行,我想创建一个包含 100 行的新列,其中列 43 到 167 的总和。列有 1 或 0。新列包含每行的总和,我将能够对具有最多遗传标记的个体进行排序。

我觉得它接近于:

data$new=sum(data$[,43:167])

【问题讨论】:

    标签: r dataframe matrix rowsum


    【解决方案1】:

    我会通过一个例子来支持你每种方法的运行时间:

    mat = matrix(runif(4e6), ncol = 50)
    

    apply函数和rowSums的比较:

    apply_func <- function(x) {
        apply(x, 1, sum)
    }
    
    r_sum <- function(x) {
        rowSums(x)
    }
    
    # Compare the methods
    microbenchmark(
        apply_func = app(mat),
        r_sum = r_sum(mat), times = 1e5
    )
    

    -------- 输出 -- 以毫秒为单位 --------

           expr       min        lq      mean    median        uq      max neval
     apply_func 207.84661 260.34475 280.14621 279.18782 294.85119 354.1821   100
          r_sum  10.76534  11.53194  13.00324  12.72792  14.34045  16.9014   100
    

    您注意到 rowSums 函数的平均时间比 apply 函数的平均时间小 21 倍。你会发现如果矩阵的列太多,经过时间的差异可能会更显着。

    【讨论】:

    • 主要目标是不管我正在处理的数据集如何,应用于小矩阵的东西通常会应用于大基准。
    • 感谢您的建议。我做了 times = 100。
    【解决方案2】:

    您也可以使用 janitor package 中的此功能 adorn_totals。 您可以根据为 arg 提供的值对列或行求和:where

    例子:

    tibble::tibble(
    a = 10:20,
    b = 55:65,
    c = 2010:2020,
    d = c(LETTERS[1:11])) %>%
    janitor::adorn_totals(where = "col") %>%
    tibble::as_tibble()
    

    结果:

    # A tibble: 11 x 5
           a     b     c d     Total
       <int> <int> <int> <chr> <dbl>
     1    10    55  2010 A      2065
     2    11    56  2011 B      2067
     3    12    57  2012 C      2069
     4    13    58  2013 D      2071
     5    14    59  2014 E      2073
     6    15    60  2015 F      2075
     7    16    61  2016 G      2077
     8    17    62  2017 H      2079
     9    18    63  2018 I      2081
    10    19    64  2019 J      2083
    11    20    65  2020 K      2085
    

    【讨论】:

      【解决方案3】:

      这也有帮助,但毫无疑问,最好的选择是 rowSums 函数:

      data$new <- Reduce(function(x, y) {
        x + data[, y]
      }, init = data[, 43], 44:167)
      

      【讨论】:

        【解决方案4】:

        我来到这里是希望找到一种方法来获取数据表中所有列的总和,并在实施上述解决方案时遇到问题。使用cbind 函数添加所有列的总和的方法:

        cbind(data, total = rowSums(data))
        

        此方法将total 列添加到数据中,并避免使用上述解决方案尝试对所有列求和时产生的对齐问题(有关此问题的讨论,请参阅下面的帖子)。

        Adding a new column to matrix error

        【讨论】:

        【解决方案5】:

        rowSums 函数(正如 Greg 提到的那样)会做你想做的事,但是你在答案中混合了子集技术,使用“[]”时不要使用“$”,你的代码应该看起来更像:

        data$new <- rowSums( data[,43:167] )
        

        如果您想使用 sum 以外的函数,请查看 ?apply 以在行或列中应用通用函数。

        【讨论】:

        • 我不知道为什么会出现这个错误:rowSums(incomeData) 中的错误:'x' must be numeric
        • @munmunbb,您收到该错误是因为incomeData 不是数字。使用str(incomeData) 之类的东西来查看它是什么,然后可能将其转换为数字矩阵。
        【解决方案6】:

        你可以使用rowSums

        rowSums(data) 应该给你你想要的。

        【讨论】:

        • 对于 OP 问题data$new &lt;- rowSums(data[43:167])
        • 为了节省别人的时间,也许是:避免与函数 rowsum 混淆,它会做其他事情!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-25
        • 2013-04-30
        相关资源
        最近更新 更多