【问题标题】:Calculate row means on subset of columns计算列子集上的行均值
【发布时间】:2012-06-12 07:51:33
【问题描述】:

给定一个示例数据框:

C1<-c(3,2,4,4,5)
C2<-c(3,7,3,4,5)
C3<-c(5,4,3,6,3)
DF<-data.frame(ID=c("A","B","C","D","E"),C1=C1,C2=C2,C3=C3)

DF
    ID C1 C2 C3
  1  A  3  3  5
  2  B  2  7  4
  3  C  4  3  3
  4  D  4  4  6
  5  E  5  5  3

创建包含ID 列和每行平均值的第二个数据框的最佳方法是什么?像这样的:

ID  Mean
A    3.66
B    4.33
C    3.33
D    4.66
E    4.33

类似于:

RM<-rowMeans(DF[,2:4])

我想让手段与他们的ID 保持一致。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    计算列子集上的行均值:

    创建一个新的 data.frame,它将 DF 的第一列指定为称为 ID 的列,并计算该行上所有其他字段的平均值,并将其放入标题为“平均值”的列中:

    data.frame(ID=DF[,1], Means=rowMeans(DF[,-1]))
      ID    Means
    1  A 3.666667
    2  B 4.333333
    3  C 3.333333
    4  D 4.666667
    5  E 4.333333
    

    【讨论】:

      【解决方案2】:

      从您的数据框DF 开始,您可以使用data.table 包:

      library(data.table)
      
      ## EDIT: As suggested by @MichaelChirico, setDT converts a
      ## data.frame to a data.table by reference and is preferred
      ## if you don't mind losing the data.frame
      setDT(DF)
      
      # EDIT: To get the column name 'Mean':
      
      DF[, .(Mean = rowMeans(.SD)), by = ID]
      
      #      ID     Mean
      # [1,]  A 3.666667
      # [2,]  B 4.333333
      # [3,]  C 3.333333
      # [4,]  D 4.666667
      # [5,]  E 4.333333
      

      【讨论】:

      • 谢谢。还要注意class(DF),您不会丢失data.frame,因为任何寻找data.frame 对象的函数都应该在setDT 之后接受DF(尤其是现在data.table是成熟的一面)
      • 如果我只想要 C2 和 C3 之间的行均值怎么办?
      • 那么你可以使用DF[, .(Mean = rowMeans(.SD)), by = ID, .SDcols = c("C2", "C3")]。参数.SDcols 确定要包含在.SD 中的列。 @user3841581
      • @BenBarnes 就我而言,我不确定我想要采用 rowMeans 的实际列数,在某些情况下它们可能是 196,而在其他情况下可能是 198,依此类推。但是一个很常见的是他们名字的首字母,就像 Mgw.1, Mgw.2 ... Mgw.196 类似 Hel.1, Hel.2 ... Hel.198 所以我想做的是不要触摸 data.table 的初始 5 列,然后是所有具有首字母 Mgw 的列,获取它们的 rowMeans 并将其分配给 MGW(删除所有单独的列,只保留一个具有平均值的列),以此类推其余列。你能指导我怎么做吗?
      • @Newbie 这听起来像是一个新问题,您应该自己发布。
      【解决方案3】:

      您可以在与 Means 对应的数据框中使用$ 创建一个新行

      DF$Mean <- rowMeans(DF[,2:4])
      

      【讨论】:

        【解决方案4】:

        使用dplyr

        library(dplyr)
        
        # exclude ID column then get mean
        DF %>%
          transmute(ID,
                    Mean = rowMeans(select(., -ID)))
        

        或者

        # select the columns to include in mean
        DF %>%
          transmute(ID,
                    Mean = rowMeans(select(., C1:C3)))
        
        #   ID     Mean
        # 1  A 3.666667
        # 2  B 4.333333
        # 3  C 3.333333
        # 4  D 4.666667
        # 5  E 4.333333
        

        【讨论】:

          【解决方案5】:

          (从最新的Tidyr 更新中使用pivot_longerpivot_wider 的另一种解决方案)

          您应该尝试使用 pivot_longer 将数据从宽格式变为长格式 阅读有关 pivot_longer 和 pivot_wider 的最新 tidyR 更新 (https://tidyr.tidyverse.org/articles/pivot.html)

          library(tidyverse)
          C1<-c(3,2,4,4,5)
          C2<-c(3,7,3,4,5)
          C3<-c(5,4,3,6,3)
          DF<-data.frame(ID=c("A","B","C","D","E"),C1=C1,C2=C2,C3=C3)
          

          在这里输出

            ID     mean
            <fct> <dbl>
          1 A      3.67
          2 B      4.33
          3 C      3.33
          4 D      4.67
          5 E      4.33
          

          【讨论】:

            【解决方案6】:

            rowMeans 很好,但如果您仍然想了解apply 系列函数,这是开始理解它的好机会。

            DF['Mean'] <- apply(DF[,2:4], 1, mean)
            

            请注意,我正在做的作业与第一个示例略有不同。这种方法更容易将其合并到 for 循环中。

            【讨论】:

              猜你喜欢
              • 2022-01-21
              • 2019-01-27
              • 2012-03-09
              • 2020-09-07
              • 1970-01-01
              • 2019-04-03
              相关资源
              最近更新 更多