добавление значений с использованием rowSums и Tidyverse - PullRequest
0 голосов
/ 21 февраля 2020

У меня возникают некоторые проблемы при попытке суммировать кучу столбцов в 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, все значения во второй строке между первым столбцом и столбцом 100 и т. д. c.

Используя примеры данных, которые я пришел с этим решением, используя 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))), теряя свой первый ряд, который содержит имена значений. Как лучше всего заменить NA и NaN, не изменяя значения строки первой строки на 0?

  • Тип столбцов, которые я добавляю, является целочисленным при преобразовании их заранее mutate_if(~!is.numeric(.x), as.numeric). Должен ли я следовать тому же подходу в случае, если у меня есть DBL?

Спасибо!

1 Ответ

1 голос
/ 21 февраля 2020

Вот один из способов сделать это после преобразования данных в более длинный формат: для каждого 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
.
...