【问题标题】:adding values using rowSums and tidyverse使用 rowSums 和 tidyverse 添加值
【发布时间】:2020-02-21 01:15:59
【问题描述】:

我在尝试对 R 中的一堆列求和时遇到了一些问题。我正在分析一个巨大的数据集,因此我正在复制一个样本。假数据。

这是数据的样子(我有 800 列)。

library(data.table)
dataset <- data.table(name = c("A", "B", "C", "D"), a1 = 1:4, a2 = c(1,2,NaN,5), a3 = 1:4, a4 = 1:4, a5 = c(1,2,NA,5), a6 = 1:4, a8 = 1:4)
dataset

我想要做的是将 100 列的存储桶中的列相加,例如,第一列和第 100 列之间的第一行中的所有值,第一列和第 1 列之间的第一行中的所有值第 200 列,第 1 列和第 100 列之间的第二行中的所有值,等等。

使用我在此解决方案中使用rowSums 提供的示例数据。

dataset %>%
  mutate_if(~!is.numeric(.x), as.numeric) %>%
  mutate_all(funs(replace_na(., 0)))  %>%
  mutate(sum = rowSums(.[,paste("a", 1:3, sep="")])) %>%
  mutate(sum1 = rowSums(.[,paste("a", 4:5, sep="")])) %>%
  mutate(sum2 = rowSums(.[,paste("a", 6:8, sep="")]))

但我收到以下错误:

Error in `[.data.frame`(., , paste("a", 6:8, sep = "")) : undefined columns selected

因为数据不包括 a7 列。

原始数据在 a1 和 a800 之间缺少一堆列,因此解决此问题将是使其正常工作的关键。

处理和解决此错误的最佳方法是什么?

另外,关于我编写的代码,我还有几个问题:

  • 有没有更聪明的方法来选择列 a1 和 a100 而不是使用这种方法 .[,paste("a", 1:3, sep="")]?我有兴趣按名称选择列。我不想通过列的位置来选择它,因为有时 a100 并不意味着那是第 100 列。

  • 另外,我将 NA 和 NaN 转换为 0,以便能够对行求和。我正在这样做mutate_all(funs(replace_na(., 0))),丢失了我的第一行而不是包含值的名称。在不将第一行的字符串值更改为 0 的情况下替换 NA 和 NaN 的最佳方法是什么?

  • 我添加的列的类型是整数,因为我事先转换了它们 mutate_if(~!is.numeric(.x), as.numeric) 。如果我有 dbl,我应该采用相同的方法吗?

谢谢!

【问题讨论】:

    标签: r tidyverse rowsum


    【解决方案1】:

    这是将数据转换为更长格式后执行此操作的一种方法,对于每个name,我们创建一组n 行并采用sum

    library(dplyr)
    library(tidyr)
    
    n <- 2 #No of columns to bucket. Change this to 100 for your case.
    
    dataset %>%
      pivot_longer(cols = -name, names_to = 'col') %>%
      group_by(name) %>%
      group_by(grp = rep(seq_len(n()), each = n, length.out = n()), add = TRUE) %>%
      summarise(value = sum(value, na.rm = TRUE)) %>%
      #If needed in wider format again
      pivot_wider(names_from = grp, values_from = value, names_prefix = 'col')
    
    #  name   col1  col2  col3  col4
    #  <chr> <dbl> <dbl> <dbl> <dbl>
    #1 A         2     2     2     1
    #2 B         4     4     4     2
    #3 C         3     6     3     3
    #4 D         9     8     9     4
    

    【讨论】:

    • 谢谢罗娜。这真的很有帮助。如果要存储的列数并不总是恒定的,我该怎么办?例如,假设我要添加 50、100、200、350。
    • @console.log 您可以将它们存储在向量len &lt;- c(50, 100, 200, 350) 中,然后替换第二个group_by,如group_by(grp = rep(seq_along(len), len), add = TRUE)。保持剩余的链条不变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多