[r] dplyr을 사용하여 여러 열의 합계

내 질문에는 데이터 프레임의 여러 열에 걸쳐 값을 합산하고을 사용 하여이 합계에 해당하는 새 열을 만드는 것이 포함됩니다 dplyr. 열의 데이터 항목은 binary (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]))


답변

특정 열만 합산하려면 다음과 같이 사용합니다.

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의 구문을 사용할 수 있습니다 .


답변

특정 패턴 이름을 가진 변수를 합산하기 위해 정규식 일치를 사용합니다. 예를 들면 :

df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
                    sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))

이렇게하면 데이터 프레임의 특정 변수 그룹의 합계로 둘 이상의 변수를 만들 수 있습니다.


답변

이 문제가 자주 발생하며 가장 쉬운 방법 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처리 단계 스트림 내의 어느 곳에서나 발생할 수 있습니다 . 마지막으로, 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데이터 정리 단계 의 흐름에 적합하지 않다는 것 입니다.


답변

reduce()from을 사용하면 모든 행에 대한 반복을 피하고 벡터화 된 작업을 활용하기 때문에 purrr보다 약간 빠르며 rowSums확실히 빠릅니다 apply.

library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), `+`))

참조 타이밍에 대한


답변

의 최신 버전에서는 with 를 사용하여 특정 행 단위 변형이없는 함수에 대해 행 단위 집계를 수행 dplyr할 수 있지만 행 단위 변형이있는 경우 더 빠릅니다.rowwise()c_across

이후 rowwise()그룹화의 단지 특별한 형태이며에 동사는 가능성이 파이프를 원하는 것이다 작업 방식을 변경 ungroup()하여 행 방향으로 작업을 수행 한 후.

행 범위를 선택하려면 :

df %>%
  dplyr::rowwise() %>%
  dplyr::mutate(sumrange = sum(dplyr::c_across(x1:x5), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

유형별로 행을 선택하려면 :

df %>%
  dplyr::rowwise() %>%
  dplyr::mutate(sumnumeric = sum(c_across(where(is.numeric)), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

특정 경우에 행 방식 변형이 있으므로 다음을 수행 할 수 있습니다 ( across대신 사용에 유의하십시오 ).

df %>%
  dplyr::mutate(sumrow = rowSums(dplyr::across(x1:x5), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

자세한 내용은 rowwise 페이지를 참조하세요 .


답변