Programing

그룹별로 변수를 합산하는 방법

lottogame 2020. 3. 11. 00:41
반응형

그룹별로 변수를 합산하는 방법


두 개의 데이터 열이 있다고 가정 해 봅시다. 첫 번째는 "First", "Second", "Third"등과 같은 범주를 포함합니다. 두 번째에는 "First"를 본 횟수를 나타내는 숫자가 있습니다.

예를 들면 다음과 같습니다.

Category     Frequency
First        10
First        15
First        5
Second       2
Third        14
Third        20
Second       3

범주별로 데이터를 정렬하고 빈도를 합치고 싶습니다.

Category     Frequency
First        30
Second       5
Third        34

R에서 어떻게해야합니까?


사용 aggregate:

aggregate(x$Frequency, by=list(Category=x$Category), FUN=sum)
  Category  x
1    First 30
2   Second  5
3    Third 34

위의 예에서 여러 치수를에 지정할 수 있습니다 list. 동일한 데이터 유형의 여러 집계 메트릭은 다음을 통해 통합 될 수 있습니다 cbind.

aggregate(cbind(x$Frequency, x$Metric2, x$Metric3) ...

(@thelatemail 주석 포함), aggregate수식 인터페이스도 있습니다

aggregate(Frequency ~ Category, x, sum)

또는 여러 열을 집계하려는 경우 .표기법을 사용할 수 있습니다 (한 열에도 적용 가능).

aggregate(. ~ Category, x, sum)

또는 tapply:

tapply(x$Frequency, x$Category, FUN=sum)
 First Second  Third 
    30      5     34 

이 데이터를 사용하여 :

x <- data.frame(Category=factor(c("First", "First", "First", "Second",
                                      "Third", "Third", "Second")), 
                    Frequency=c(10,15,5,2,14,20,3))

보다 최근에는 해당 용도로 dplyr 패키지를 사용할 수도 있습니다 .

library(dplyr)
x %>% 
  group_by(Category) %>% 
  summarise(Frequency = sum(Frequency))

#Source: local data frame [3 x 2]
#
#  Category Frequency
#1    First        30
#2   Second         5
#3    Third        34

또는 여러 요약 열의 경우 (하나의 열과 함께 작동) :

x %>% 
  group_by(Category) %>% 
  summarise_each(funs(sum))

dplyr> = 0.5 업데이트 : summarise_each 에 의해 대체되었습니다 summarise_all, summarise_at그리고 summarise_if기능의 가족 dplyr있다.

또는 그룹화 할 여러 열 이있는 경우 모든 열을group_by 쉼표로 구분 하여 지정할 수 있습니다 .

mtcars %>% 
  group_by(cyl, gear) %>%                            # multiple group columns
  summarise(max_hp = max(hp), mean_mpg = mean(mpg))  # multiple summary columns

%>%연산자를 포함한 자세한 정보 는 dplyr 소개를 참조하십시오 .


rcs가 제공하는 대답은 간단하며 간단합니다. 그러나 더 큰 데이터 세트를 처리하고 성능 향상이 필요한 경우 더 빠른 대안이 있습니다.

library(data.table)
data = data.table(Category=c("First","First","First","Second","Third", "Third", "Second"), 
                  Frequency=c(10,15,5,2,14,20,3))
data[, sum(Frequency), by = Category]
#    Category V1
# 1:    First 30
# 2:   Second  5
# 3:    Third 34
system.time(data[, sum(Frequency), by = Category] )
# user    system   elapsed 
# 0.008     0.001     0.009 

data.frame과 위의 내용을 사용하여 동일한 내용과 비교해 보겠습니다.

data = data.frame(Category=c("First","First","First","Second","Third", "Third", "Second"),
                  Frequency=c(10,15,5,2,14,20,3))
system.time(aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum))
# user    system   elapsed 
# 0.008     0.000     0.015 

그리고 열을 유지하려면 다음 구문을 사용하십시오.

data[,list(Frequency=sum(Frequency)),by=Category]
#    Category Frequency
# 1:    First        30
# 2:   Second         5
# 3:    Third        34

아래 코드에서 알 수 있듯이 더 큰 데이터 세트에서는 차이가 더 두드러집니다.

data = data.table(Category=rep(c("First", "Second", "Third"), 100000),
                  Frequency=rnorm(100000))
system.time( data[,sum(Frequency),by=Category] )
# user    system   elapsed 
# 0.055     0.004     0.059 
data = data.frame(Category=rep(c("First", "Second", "Third"), 100000), 
                  Frequency=rnorm(100000))
system.time( aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum) )
# user    system   elapsed 
# 0.287     0.010     0.296 

여러 집계를 들어, 결합 할 수 lapply.SD같은 다음

data[, lapply(.SD, sum), by = Category]
#    Category Frequency
# 1:    First        30
# 2:   Second         5
# 3:    Third        34

이것은 이 질문과 다소 관련이 있습니다.

by () 함수를 사용할 수도 있습니다.

x2 <- by(x$Frequency, x$Category, sum)
do.call(rbind,as.list(x2))

다른 패키지 (plyr, reshape)는 data.frame을 반환하는 이점이 있지만 기본 함수이기 때문에 by ()에 익숙 할 가치가 있습니다.


library(plyr)
ddply(tbl, .(Category), summarise, sum = sum(Frequency))

몇 년 후 여기에 존재하지 않는 또 다른 간단한 기본 R 솔루션을 추가하기 위해 xtabs

xtabs(Frequency ~ Category, df)
# Category
# First Second  Third 
#    30      5     34 

아니면 data.frame다시 원한다면

as.data.frame(xtabs(Frequency ~ Category, df))
#   Category Freq
# 1    First   30
# 2   Second    5
# 3    Third   34

x데이터가있는 데이터 프레임 인 경우 다음이 원하는 것을 수행합니다.

require(reshape)
recast(x, Category ~ ., fun.aggregate=sum)

최근 dplyr에 이러한 유형의 작업 대부분에 대한 변환 sqldf이되었지만 패키지는 여전히 일부로 훌륭합니다 (그리고 IMHO 더 읽기 쉽습니다).

다음은이 질문에 어떻게 대답 할 수 있는지에 대한 예입니다. sqldf

x <- data.frame(Category=factor(c("First", "First", "First", "Second",
                                  "Third", "Third", "Second")), 
                Frequency=c(10,15,5,2,14,20,3))

sqldf("select 
          Category
          ,sum(Frequency) as Frequency 
       from x 
       group by 
          Category")

##   Category Frequency
## 1    First        30
## 2   Second         5
## 3    Third        34

세 번째 옵션을 추가하려면 다음을 수행하십시오.

require(doBy)
summaryBy(Frequency~Category, data=yourdataframe, FUN=sum)

편집 : 이것은 매우 오래된 대답입니다. 이제 @docendo answer 에서 와 같이 group_byand summarisefrom을 사용하는 것이 좋습니다 dplyr.


최근에 추가 된 기능은 dplyr::tally()이제 그 어느 때보 다 쉬워졌습니다

tally(x, Category)

Category     n
First        30
Second       5
Third        34

내가 찾을 ave서로 다른 열을 다른 집계 함수를 적용 할 필요가있을 때 매우 도움 (효율적인) (당신은 / 기본 R에 충실하고자합니다) :

예 :

이 입력이 주어지면 :

DF <-                
data.frame(Categ1=factor(c('A','A','B','B','A','B','A')),
           Categ2=factor(c('X','Y','X','X','X','Y','Y')),
           Samples=c(1,2,4,3,5,6,7),
           Freq=c(10,30,45,55,80,65,50))

> DF
  Categ1 Categ2 Samples Freq
1      A      X       1   10
2      A      Y       2   30
3      B      X       4   45
4      B      X       3   55
5      A      X       5   80
6      B      Y       6   65
7      A      Y       7   50

우리는 그룹에 의해 원하는 Categ1Categ2와의 합을 계산 Samples하고의 의미 Freq.
다음을 사용하여 가능한 해결책이 있습니다 ave.

# create a copy of DF (only the grouping columns)
DF2 <- DF[,c('Categ1','Categ2')]

# add sum of Samples by Categ1,Categ2 to DF2 
# (ave repeats the sum of the group for each row in the same group)
DF2$GroupTotSamples <- ave(DF$Samples,DF2,FUN=sum)

# add mean of Freq by Categ1,Categ2 to DF2 
# (ave repeats the mean of the group for each row in the same group)
DF2$GroupAvgFreq <- ave(DF$Freq,DF2,FUN=mean)

# remove the duplicates (keep only one row for each group)
DF2 <- DF2[!duplicated(DF2),]

결과 :

> DF2
  Categ1 Categ2 GroupTotSamples GroupAvgFreq
1      A      X               6           45
2      A      Y               9           40
3      B      X               7           50
6      B      Y               6           65

Rfast 패키지 의 함수 group.sum사용할 수 있습니다 .

Category <- Rfast::as_integer(Category,result.sort=FALSE) # convert character to numeric. R's as.numeric produce NAs.
result <- Rfast::group.sum(Frequency,Category)
names(result) <- Rfast::Sort(unique(Category)
# 30 5 34

Rfast 는 많은 그룹 기능을 가지고 있으며group.sum그중 하나입니다.


사용하는 cast대신 recast(참고 'Frequency'지금 'value')

df  <- data.frame(Category = c("First","First","First","Second","Third","Third","Second")
                  , value = c(10,15,5,2,14,20,3))

install.packages("reshape")

result<-cast(df, Category ~ . ,fun.aggregate=sum)

얻을 :

Category (all)
First     30
Second    5
Third     34

참고 URL : https://stackoverflow.com/questions/1660124/how-to-sum-a-variable-by-group

반응형