【问题标题】:Sum Values of Every Column in Data Frame with Conditional For Loop使用条件 For 循环对数据框中每一列的值求和
【发布时间】:2018-12-04 17:19:12
【问题描述】:

所以我想通过一个数据集并根据我的第一列的条件对每一列的值求和。到目前为止的数据和我的代码如下所示:

x    v1    v2    v3
1    0     1     5
2    4     2     10 
3    5     3     15
4    1     4     20

for(i in colnames(data)){
    if(data$x>2){
        x1 <-sum(data[[i]])
        }
    else{
        x2 <-sum(data[[i]])
        }
      }

我的假设是 for 循环会按名称从数据中调用每一列,然后根据它们是否与列 x 的条件相匹配,对每列中的值求和。

我想将每列中的一半值相加并将它们分配给值 x1,并对余数执行相同的操作,将其分配给 x2。我不断收到一条错误消息:

the condition has length > 1 and only the first element will be used

我做错了什么,有没有更好的方法来解决这个问题?理想情况下,我想要一个如下所示的表格:

       v1    v2    v3
x1     6     7     35
x2     4     3     15

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    这是dplyr 解决方案。首先,我定义了数据框。

    df <- read.table(text = "x    v1    v2    v3
    1    0     1     5
    2    4     2     10 
    3    5     3     15
    4    1     4     20", header = TRUE)  
    
    #   x v1 v2 v3
    # 1 1  0  1  5
    # 2 2  4  2 10
    # 3 3  5  3 15
    # 4 4  1  4 20
    

    然后,我创建一个标签 (x_check) 以根据您的标准 (x &gt; 2) 指示每行所属的组,按此标签分组,并使用名称中的 v 汇总每一列sum.

    # Load library
    library(dplyr)
    
    df %>% 
      mutate(x_check = ifelse(x>2, "x1", "x2")) %>% 
      group_by(x_check) %>% 
      summarise_at(vars(contains("v")), funs(sum))
    
    # # A tibble: 2 x 4
    #   x_check    v1    v2    v3
    #   <chr>   <int> <int> <int>
    # 1 x1          6     7    35
    # 2 x2          4     3    15
    

    【讨论】:

      【解决方案2】:

      不确定我是否正确理解了您的意图,但这里是您如何使用基础 R 重现结果:

      df <- data.frame(
        x = c(1:4),
        v1 = c(0, 4, 5, 1),
        v2 = 1:4,
        v3 = (1:4)*5
      )
      
      x1 <- colSums(df[df$x > 2, 2:4, drop = FALSE])
      x2 <- colSums(df[df$x <= 2, 2:4, drop = FALSE])
      

      在哪里

      • df[df$x &gt; 2, 2:4, drop = FALSE] 将创建 df 的一个子集,其中行满足 df$x &gt; 2 并且列是 2:4(表示第二、第三和第四列),drop = FALSE 主要是为了防止 R 简化结果一些特殊情况
      • colSums 对子集的 data.frame 进行逐列求和

      如果您的 x 列确实是一个条件(例如 logical vector),您可以这样做

      x1 <- colSums(df[df$x, 2:4, drop = FALSE])
      x2 <- colSums(df[!df$x, 2:4, drop = FALSE])
      

      请注意,获取结果不需要循环,对于 R,您应该尽可能使用矢量化函数。

      更一般地说,您可以使用 aggregate 进行此类聚合:

      aggregate(df[, 2:4], by = list(condition = df$x <= 2), FUN = sum)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-06
        • 2020-06-05
        • 1970-01-01
        • 1970-01-01
        • 2017-04-19
        • 2021-07-21
        • 2022-01-02
        相关资源
        最近更新 更多