그룹별 변수 합계 방법
열이 두 개인 데이터 프레임이 있습니다.첫 번째 열에는 "첫 번째", "두 번째", "세 번째"와 같은 범주가 포함되어 있고, 두 번째 열에는 "범주"에서 특정 그룹을 본 횟수를 나타내는 숫자가 포함되어 있습니다.
예:
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) ...
댓글 보기), (@latemail ),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(across(everything(), sum))
은 기본 데이터 함수를 몇 가지 입니다.mtcars
:
# several summary columns with arbitrary names
mtcars %>%
group_by(cyl, gear) %>% # multiple group columns
summarise(max_hp = max(hp), mean_mpg = mean(mpg)) # multiple summary columns
# summarise all columns except grouping columns using "sum"
mtcars %>%
group_by(cyl) %>%
summarise(across(everything(), sum))
# summarise all columns except grouping columns using "sum" and "mean"
mtcars %>%
group_by(cyl) %>%
summarise(across(everything(), list(mean = mean, sum = sum)))
# multiple grouping columns
mtcars %>%
group_by(cyl, gear) %>%
summarise(across(everything(), list(mean = mean, sum = sum)))
# summarise specific variables, not all
mtcars %>%
group_by(cyl, gear) %>%
summarise(across(c(qsec, mpg, wt), list(mean = mean, sum = sum)))
# summarise specific variables (numeric columns except grouping columns)
mtcars %>%
group_by(gear) %>%
summarise(across(where(is.numeric), list(mean = mean, sum = sum)))
다음을 포함한 더 많은 정보를 참조하십시오.%>%
연산자, 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
기준() 기능도 사용할 수 있습니다.
x2 <- by(x$Frequency, x$Category, sum)
do.call(rbind,as.list(x2))
이러한 다른 패키지(plyr, reshape)는 data.frame을 반환하는 이점이 있지만 기본 함수이므로 ()에 익숙해질 가치가 있습니다.
년 후, 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
library(plyr)
ddply(tbl, .(Category), summarise, sum = sum(Frequency))
한다면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)
편집: 이것은 매우 오래된 대답입니다.이제 사용할 것을 권장합니다.group_by
그리고.summarise
부터dplyr
@docendo 답변에서와 같이.
행렬 또는 데이터 프레임의 그룹별 합계를 반환하는 또 다른 솔루션은 짧고 빠릅니다.
rowsum(x$Frequency, x$Category)
다른 열에 다른 집계 함수를 적용해야 할 때(그리고 기본 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
우리는 그룹을 만들고 싶습니다.Categ1
그리고.Categ2
그리고 다음의 합을 계산합니다.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
부터dplyr 1.0.0
,그across()
사용할 수 있는 기능:
df %>%
group_by(Category) %>%
summarise(across(Frequency, sum))
Category Frequency
<chr> <int>
1 First 30
2 Second 5
3 Third 34
여러 변수에 관심이 있는 경우:
df %>%
group_by(Category) %>%
summarise(across(c(Frequency, Frequency2), sum))
Category Frequency Frequency2
<chr> <int> <int>
1 First 30 55
2 Second 5 29
3 Third 34 190
그리고 도우미 선택을 사용하여 변수를 선택합니다.
df %>%
group_by(Category) %>%
summarise(across(starts_with("Freq"), sum))
Category Frequency Frequency2 Frequency3
<chr> <int> <int> <dbl>
1 First 30 55 110
2 Second 5 29 58
3 Third 34 190 380
표본 데이터:
df <- read.table(text = "Category Frequency Frequency2 Frequency3
1 First 10 10 20
2 First 15 30 60
3 First 5 15 30
4 Second 2 8 16
5 Third 14 70 140
6 Third 20 120 240
7 Second 3 21 42",
header = TRUE,
stringsAsFactors = FALSE)
기능을 사용할 수 있습니다.group.sum
Rfast 패키지에서.
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
library(tidyverse)
x <- data.frame(Category= c('First', 'First', 'First', 'Second', 'Third', 'Third', 'Second'),
Frequency = c(10, 15, 5, 2, 14, 20, 3))
count(x, Category, wt = Frequency)
그룹별로 변수를 합치는 좋은 방법은 다음과 같습니다.
rowsum(numericToBeSummedUp, groups)
기지에서여기만collapse::fsum
그리고.Rfast::group.sum
더 빨라졌습니다.
속도 및 메모리 소비와 관련하여
collapse::fsum(numericToBeSummedUp, groups)
그룹화된 데이터 프레임을 사용할 때 속도를 높일 수 있는 것이 주어진 예에서 가장 우수했습니다.
GDF <- collapse::fgroup_by(DF, g) #Create a grouped data.frame with group g
#GDF <- collapse::gby(DF, g) #Alternative
collapse::fsum(GDF) #Calculate sum per group
이는 데이터 세트가 그룹별로 하위 데이터 세트로 분할된 시점에 근접합니다.
여러 방법에 대한 벤치마크를 통해 단일 열을 요약할 수 있음을 알 수 있습니다.collapse::fsum
보다 2배 더 빨랐습니다.Rfast::group.sum
보다 7배 더 빠릅니다.rowsum
그 뒤를 이었습니다.tapply
,data.table
,by
그리고.dplyr
.xtabs
그리고.aggregate
가장 느립니다.
두 개의 열collapse::fsum
다시 가장 빠릅니다. 3배 더 빠릅니다.Rfast::group.sum
그보다 5배 더 빠름rowsum
그 다음에 다음과 같습니다.data.table
,tapply
,by
그리고.dplyr
.다시.xtabs
그리고.aggregate
가장 느립니다.
벤치마크
set.seed(42)
n <- 1e5
DF <- data.frame(g = as.factor(sample(letters, n, TRUE))
, x = rnorm(n), y = rnorm(n) )
library(magrittr)
일부 방법에서는 집계 속도를 높이는 데 도움이 될 수 있는 작업을 수행할 수 있습니다.
DT <- data.table::as.data.table(DF)
data.table::setkey(DT, g)
DFG <- collapse::gby(DF, g)
DFG1 <- collapse::gby(DF[c("g", "x")], g)
# Optimized dataset for this aggregation task
# This will also consume time!
DFS <- lapply(split(DF[c("x", "y")], DF["g"]), as.matrix)
DFS1 <- lapply(split(DF["x"], DF["g"]), as.matrix)
열 하나를 요약합니다.
bench::mark(check = FALSE
, "aggregate" = aggregate(DF$x, DF["g"], sum)
, "tapply" = tapply(DF$x, DF$g, sum)
, "dplyr" = DF %>% dplyr::group_by(g) %>% dplyr::summarise(sum = sum(x))
, "data.table" = data.table::as.data.table(DF)[, sum(x), by = g]
, "data.table2" = DT[, sum(x), by = g]
, "by" = by(DF$x, DF$g, sum)
, "xtabs" = xtabs(x ~ g, DF)
, "rowsum" = rowsum(DF$x, DF$g)
, "Rfast" = Rfast::group.sum(DF$x, DF$g)
, "base Split" = lapply(DFS1, colSums)
, "base Split Rfast" = lapply(DFS1, Rfast::colsums)
, "collapse" = collapse::fsum(DF$x, DF$g)
, "collapse2" = collapse::fsum(DFG1)
)
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>
# 1 aggregate 20.43ms 21.88ms 45.7 16.07MB 59.4 10 13
# 2 tapply 1.24ms 1.39ms 687. 1.53MB 30.1 228 10
# 3 dplyr 3.28ms 4.81ms 209. 2.42MB 13.1 96 6
# 4 data.table 1.59ms 2.47ms 410. 4.69MB 87.7 145 31
# 5 data.table2 1.52ms 1.93ms 514. 2.38MB 40.5 190 15
# 6 by 2.15ms 2.31ms 396. 2.29MB 26.7 148 10
# 7 xtabs 7.78ms 8.91ms 111. 10.54MB 50.0 31 14
# 8 rowsum 951.36µs 1.07ms 830. 1.15MB 24.1 378 11
# 9 Rfast 431.06µs 434.53µs 2268. 2.74KB 0 1134 0
#10 base Split 213.42µs 219.66µs 4342. 256B 12.4 2105 6
#11 base Split Rfast 76.88µs 81.48µs 10923. 65.05KB 16.7 5232 8
#12 collapse 121.03µs 122.92µs 7965. 256B 2.01 3961 1
#13 collapse2 85.97µs 88.67µs 10749. 256B 4.03 5328 2
두 열을 합
bench::mark(check = FALSE
, "aggregate" = aggregate(DF[c("x", "y")], DF["g"], sum)
, "tapply" = list2DF(lapply(DF[c("x", "y")], tapply, list(DF$g), sum))
, "dplyr" = DF %>% dplyr::group_by(g) %>% dplyr::summarise(x = sum(x), y = sum(y))
, "data.table" = data.table::as.data.table(DF)[,.(sum(x),sum(y)), by = g]
, "data.table2" = DT[,.(sum(x),sum(y)), by = g]
, "by" = lapply(DF[c("x", "y")], by, list(DF$g), sum)
, "xtabs" = xtabs(cbind(x, y) ~ g, DF)
, "rowsum" = rowsum(DF[c("x", "y")], DF$g)
, "Rfast" = list2DF(lapply(DF[c("x", "y")], Rfast::group.sum, DF$g))
, "base Split" = lapply(DFS, colSums)
, "base Split Rfast" = lapply(DFS, Rfast::colsums)
, "collapse" = collapse::fsum(DF[c("x", "y")], DF$g)
, "collapse2" = collapse::fsum(DFG)
)
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>
# 1 aggregate 25.87ms 26.36ms 37.7 20.89MB 132. 4 14
# 2 tapply 2.65ms 3.23ms 312. 3.06MB 22.5 97 7
# 3 dplyr 4.27ms 6.02ms 164. 3.19MB 13.3 74 6
# 4 data.table 2.33ms 3.19ms 309. 4.72MB 57.0 114 21
# 5 data.table2 2.22ms 2.81ms 355. 2.41MB 19.8 161 9
# 6 by 4.45ms 5.23ms 190. 4.59MB 22.5 59 7
# 7 xtabs 10.71ms 13.14ms 76.1 19.7MB 145. 11 21
# 8 rowsum 1.02ms 1.07ms 850. 1.15MB 23.8 393 11
# 9 Rfast 841.57µs 846.88µs 1150. 5.48KB 0 575 0
#10 base Split 360.24µs 368.28µs 2652. 256B 8.16 1300 4
#11 base Split Rfast 113.95µs 119.81µs 7540. 65.05KB 10.3 3661 5
#12 collapse 201.31µs 204.83µs 4724. 512B 2.01 2350 1
#13 collapse2 156.95µs 161.79µs 5408. 512B 2.02 2683 1
사용할 수 있습니다.rowsum
주파수를 계산하는 함수입니다.
data("mtcars")
df <- mtcars
df$cyl <- as.factor(df$cyl)
머리 모양은 다음과 같습니다.
wt mpg cyl
<dbl> <dbl> <fct>
Mazda RX4 2.620 21.0 6
Mazda RX4 Wag 2.875 21.0 6
Datsun 710 2.320 22.8 4
그리고나서,
rowsum(df$mpg, df$cyl) #values , group
4 293.3
6 138.2
8 211.4
와 함께dplyr 1.1.0
그리고 위에, 당신은 사용할 수 있습니다..by
에summarise
이 바로 가기는 사용할 수 없습니다.group_by
를 반환합니다.ungroup
ed 데이터 프레임:
library(dplyr)
x %>%
summarise(Frequency = sum(Frequency), .by = Category)
언급URL : https://stackoverflow.com/questions/1660124/how-to-sum-a-variable-by-group
'IT' 카테고리의 다른 글
SQL Plus 현재 디렉터리 변경 (0) | 2023.07.07 |
---|---|
HTTP 모듈에서 세션 상태에 액세스할 수 있습니까? (0) | 2023.07.07 |
Mongodb 서비스가 시작되지 않습니다. (0) | 2023.07.07 |
빈 문자열이 split() 결과로 반환되는 이유는 무엇입니까? (0) | 2023.07.07 |
(이름 없이) 지정된 번호에서 숫자만 추출하려면 어떻게 해야 합니까? (0) | 2023.07.07 |