【问题标题】:Add column to each data frame within list with function rowSums and range of columns使用函数 rowSums 和列范围向列表中的每个数据框添加列
【发布时间】:2020-10-01 17:36:40
【问题描述】:

所以。下面可以作为真实列表的一个小例子。

a <- data.frame(
  x = c("A","A","A","A","A"),
  y = c(1,2,3,4,5),
  z = c(1,2,3,4,5))

b <- data.frame(
  x = c("A","A","A","A","A"),
  y = c(1,2,3,4,5),
  z = c(1,2,3,4,5))

c <- data.frame(
  x = c("A","A","A","A","A"),
  y = c(1,2,3,4,5),
  z = c(1,2,3,4,5))

l <- list(a,b,c)

从第二列到最后一列 - 在每个数据帧上 - 我想将总和作为新列添加到每个数据帧。

我试过了:

lapply(l, function(x) rowSums(x[2:ncol(x)]))

返回正确的总和,但不将它们添加到数据帧中。

我也试过了:

lapply(l, transform, sum = y + z)

这给了我正确的结果但不够灵活,因为我并不总是知道每个数据框有多少列以及它们有什么名称。我唯一知道的是,我必须从第二列开始到结束。我尝试将这两种方法结合起来,但我不知道该怎么做。

谢谢

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    试试这个。您可以在列中使用索引并排除第一个变量,这样就不会有关于为了获得行和而拥有多少额外变量的问题。代码如下:

    #Compute rowsums
    l1 <- lapply(l,function(x) {x$RowSum<-rowSums(x[,-1],na.rm=T);return(x)})
    

    输出:

    l1
    [[1]]
      x y z RowSum
    1 A 1 1      2
    2 A 2 2      4
    3 A 3 3      6
    4 A 4 4      8
    5 A 5 5     10
    
    [[2]]
      x y z RowSum
    1 A 1 1      2
    2 A 2 2      4
    3 A 3 3      6
    4 A 4 4      8
    5 A 5 5     10
    
    [[3]]
      x y z RowSum
    1 A 1 1      2
    2 A 2 2      4
    3 A 3 3      6
    4 A 4 4      8
    5 A 5 5     10
    

    【讨论】:

      【解决方案2】:

      以下是如何组合您的尝试。我使用data[-1] 而不是data[2:ncol(data)],因为它看起来更简单,但两者都应该可以工作。

      lapply(l, function(data) transform(data, sum = rowSums(data[-1])))
      

      不幸的是,如果匿名函数的参数名称与列名称相同,transform 将会混淆 - data[-1] 需要查看数据框,而不是特定列。 (我原来是用function(x)而不是function(data),这导致了错误,因为有一个名为x的列。从这个角度来看,Duck的回答更安全一些。)

      【讨论】:

      • 谢谢格雷戈尔。我收到一个错误,x 必须是数字。我的列是整数,但我认为这也可能有效。现在我首先必须检查如何将它们全部转换为数字,然后再尝试使用您的代码。
      • 整数是数字 - 仔细检查 all 您的非第一列是否是数字(包括整数)。尝试lapply(l, function(x) {x[-1]; x[!is.numeric(x)]}) 查看任何非数字列。
      • 它们是整数。他们全部。与原始数据框的不同之处在于,我不想从第 2 列开始,而是从第 3 列开始。我只需要将 data[-1] 固定到 data[-2] 吗?
      • 用 data[3:ncol(data)] 而不是 data[-1] 修复了它。谢谢!
      • 交替 data[-(1:2)] 删除第一和第二列。或 Filter(is.numeric, data) 用于所有数字列。
      【解决方案3】:

      这行得通吗:

      > add_col <- function(df){
      +                         df[(ncol(df)+1)] = rowSums(df[2:ncol(df)])
      +                         df
      +                       }
      > lapply(l, add_col)  
      [[1]]
        x y z V4
      1 A 1 1  2
      2 A 2 2  4
      3 A 3 3  6
      4 A 4 4  8
      5 A 5 5 10
      
      [[2]]
        x y z V4
      1 A 1 1  2
      2 A 2 2  4
      3 A 3 3  6
      4 A 4 4  8
      5 A 5 5 10
      
      [[3]]
        x y z V4
      1 A 1 1  2
      2 A 2 2  4
      3 A 3 3  6
      4 A 4 4  8
      5 A 5 5 10
      
      > 
      

      以 sum 作为列名:

      > add_col <- function(df){
      +                         df['sum'] = rowSums(df[2:ncol(df)])
      +                         df
      +                       }
      > lapply(l, add_col)  
      [[1]]
        x y z sum
      1 A 1 1   2
      2 A 2 2   4
      3 A 3 3   6
      4 A 4 4   8
      5 A 5 5  10
      
      [[2]]
        x y z sum
      1 A 1 1   2
      2 A 2 2   4
      3 A 3 3   6
      4 A 4 4   8
      5 A 5 5  10
      
      [[3]]
        x y z sum
      1 A 1 1   2
      2 A 2 2   4
      3 A 3 3   6
      4 A 4 4   8
      5 A 5 5  10
      

      【讨论】:

      • 这是唯一一个在我的原始数据框上工作的。唯一的事情是,我得到了一个有趣的列名(...7)。
      • 是的,您可以稍后使用 names() 函数指定名称。
      • 或者你也可以使用 lapply(l, function(x) setNames(x, c('Col1', 'Col2', 'Col3', 'Col4'))) 。跨度>
      • 感谢您的帮助!你的也可以,但我更喜欢另一种我有正确名称的方法。
      • 已对代码稍作修改以满足您的要求。
      【解决方案4】:

      使用tidyverse

      library(tidyverse)
      map(l, ~.x %>% mutate(Sum := apply(.x[-1], 1, sum)))
      
      #> [[1]]
      #>   x y z Sum
      #> 1 A 1 1   2
      #> 2 A 2 2   4
      #> 3 A 3 3   6
      #> 4 A 4 4   8
      #> 5 A 5 5  10
      #> 
      #> [[2]]
      #>   x y z Sum
      #> 1 A 1 1   2
      #> 2 A 2 2   4
      #> 3 A 3 3   6
      #> 4 A 4 4   8
      #> 5 A 5 5  10
      #> 
      #> [[3]]
      #>   x y z Sum
      #> 1 A 1 1   2
      #> 2 A 2 2   4
      #> 3 A 3 3   6
      #> 4 A 4 4   8
      #> 5 A 5 5  10
      

      reprex package (v0.3.0) 于 2020 年 9 月 30 日创建

      【讨论】:

        【解决方案5】:

        我们可以使用mapmutate

        library(purrr)
        library(dplyr)
        map(l, ~ .x %>%
                    mutate(sum = rowSums(select(., -1))))
        

        c_across

        map(l, ~ .x %>%
                   rowwise() %>%
                   mutate(sum = sum(c_across(-1), na.rm = TRUE)) %>%
                   ungroup)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-28
          相关资源
          最近更新 更多