Ответ 1
Как насчет
суммировать каждый столбец
df %>%
replace(is.na(.), 0) %>%
summarise_all(funs(sum))
подводить итоги каждого ряда
df %>%
replace(is.na(.), 0) %>%
mutate(sum = rowSums(.[1:5]))
Мой вопрос включает в себя суммирование значений по нескольким столбцам фрейма данных и создание нового столбца, соответствующего этому суммированию, с помощью dplyr
. Записи данных в столбцах двоичные (0,1). Я думаю о разумном значении функции summarise_each
или mutate_each
dplyr
. Ниже приведен минимальный пример кадра данных:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
> df
x1 x2 x3 x4 x5
1 1 1 0 1 1
2 0 1 1 0 1
3 0 NA 0 NA NA
4 NA 1 1 1 1
5 0 1 1 0 1
6 1 0 0 0 1
7 1 NA NA NA NA
8 NA NA NA 0 1
9 0 0 0 0 0
10 1 1 1 1 1
Я мог бы использовать что-то вроде:
df <- df %>% mutate(sumrow= x1 + x2 + x3 + x4 + x5)
но это будет связано с записью имен каждого из столбцов. У меня есть 50 столбцов. Кроме того, имена столбцов меняются при разных итерациях цикла, в котором я хочу реализовать это поэтому я хотел бы попытаться избежать необходимости указывать имена столбцов.
Как я могу сделать это наиболее эффективно? Будем очень благодарны любой помощи.
Как насчет
суммировать каждый столбец
df %>%
replace(is.na(.), 0) %>%
summarise_all(funs(sum))
подводить итоги каждого ряда
df %>%
replace(is.na(.), 0) %>%
mutate(sum = rowSums(.[1:5]))
Я бы использовал регулярное выражение для суммирования по переменным с определенными именами шаблонов. Например:
df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))
Таким образом, вы можете создать более одной переменной в виде суммы определенной группы переменных вашего фрейма данных.
Если вы хотите суммировать только определенные столбцы, я бы использовал что-то вроде этого:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>% select(x3:x5) %>% rowSums(na.rm=TRUE) -> df$x3x5.total
head(df)
Таким образом вы можете использовать синтаксис dplyr::select
.
Я часто сталкиваюсь с этой проблемой, и самый простой способ сделать это - использовать функцию apply()
в команде mutate
.
library(tidyverse)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>%
mutate(sum = select(., x1:x5) %>% apply(1, sum, na.rm=TRUE))
Здесь вы можете использовать все, что вы хотите, чтобы выбрать столбцы, используя стандартные приемы dplyr
(например, starts_with()
или contains()
). Выполнив всю работу в рамках одной команды mutate
, это действие может произойти в любом dplyr
потока обработки dplyr
. Наконец, используя функцию apply()
, вы можете гибко использовать любую необходимую вам сводку, включая собственную функцию суммирования.
В качестве альтернативы, если идея использования функции, отличной от tidyverse, непривлекательна, вы можете собрать столбцы, суммировать их и, наконец, присоединить результат обратно к исходному фрейму данных.
df <- df %>% mutate( id = 1:n() ) # Need some ID column for this to work
df <- df %>%
group_by(id) %>%
gather('Key', 'value', starts_with('x')) %>%
summarise( Key.Sum = sum(value) ) %>%
left_join( df, . )
Здесь я использовал starts_with()
чтобы выбрать столбцы, вычислил сумму, и вы можете делать все, что хотите, со значениями NA
. Недостатком этого подхода является то, что, хотя он довольно гибок, он на самом деле не вписывается в поток шагов очистки данных dplyr
.
Использование purrr
reduce()
из purrr
немного быстрее, чем rowSums
и определенно быстрее, чем apply
, так как вы избегаете итерации по всем строкам и просто используете векторизованные операции:
library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), '+'))
Смотрите это для времени