data.frame에서 그룹당 평균
이 질문에는 이미 답변이 있습니다.
나는을 가지고 있으며 data.frame
그룹 당 평균 (즉 Month
, 아래) 을 계산해야합니다 .
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
내 원하는 출력 값 여기서, 이하 같다 Rate1
및 Rate2
그룹 수단이다. 값을 무시하고 예제를 위해 작성했습니다.
Name Rate1 Rate2
Aira 23.21 12.2
Ben 45.23 43.9
Cat 33.22 32.2
이 유형의 작업은 정확히 aggregate
설계된 것입니다.
d <- read.table(text=
'Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32', header=TRUE)
aggregate(d[, 3:4], list(d$Name), mean)
Group.1 Rate1 Rate2
1 Aira 16.33333 47.00000
2 Ben 31.33333 50.33333
3 Cat 44.66667 54.00000
여기에서 data.frame의 열 3과 4를 집계하고로 d
그룹화 d$Name
하고 mean
함수를 적용합니다 .
또는 수식 인터페이스를 사용하는 경우 :
aggregate(. ~ Name, d[-2], mean)
또는 패키지 에서 group_by
& summarise_at
를 사용 하십시오 dplyr
.
library(dplyr)
d %>%
group_by(Name) %>%
summarise_at(vars(-Month), funs(mean(., na.rm=TRUE)))
# A tibble: 3 x 3
Name Rate1 Rate2
<fct> <dbl> <dbl>
1 Aira 16.3 47.0
2 Ben 31.3 50.3
3 Cat 44.7 54.0
?summarise_at
작동 할 변수를 지정하는 많은 방법을 참조하십시오 . 여기서를 제외한vars(-Month)
모든 변수를 말합니다 . Month
package을 사용할 수도 있습니다 plyr
.
library(plyr)
ddply(d, .(Name), summarize, Rate1=mean(Rate1), Rate2=mean(Rate2))
Name Rate1 Rate2
1 Aira 16.33333 47.00000
2 Ben 31.33333 50.33333
3 Cat 44.66667 54.00000
세 번째 좋은 대안은 data.table
data.frame 클래스를 가진 package를 사용하는 것이지만 찾고있는 작업은 훨씬 빠르게 계산됩니다.
library(data.table)
mydt <- structure(list(Name = c("Aira", "Aira", "Aira", "Ben", "Ben", "Ben", "Cat", "Cat", "Cat"), Month = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), Rate1 = c(15.6396600443877, 2.15649279424609, 6.24692918928743, 2.37658797276116, 34.7500663272292, 3.28750138697048, 29.3265553981065, 17.9821839334431, 10.8639802575958), Rate2 = c(17.1680489538369, 5.84231656330206, 8.54330866437461, 5.88415184986176, 3.02064294862551, 17.2053351400752, 16.9552950199166, 2.56058000170089, 15.7496228048122)), .Names = c("Name", "Month", "Rate1", "Rate2"), row.names = c(NA, -9L), class = c("data.table", "data.frame"))
이제 각 사람 (이름)에 대해 3 개월 동안 Rate1과 Rate2의 평균을 얻으려면 : 먼저 평균을 계산할 열을 결정하십시오.
colstoavg <- names(mydt)[3:4]
이제 lapply를 사용하여 평균을 계산하려는 열의 평균을 취합니다 (colstoavg).
mydt.mean <- mydt[,lapply(.SD,mean,na.rm=TRUE),by=Name,.SDcols=colstoavg]
mydt.mean
Name Rate1 Rate2
1: Aira 8.014361 10.517891
2: Ben 13.471385 8.703377
3: Cat 19.390907 11.755166
이 작업을 수행하는 두 가지 방법 중 하나는 data.table 기반 이고 다른 하나 는 reshape2 패키지 기반입니다 . data.table 방법은 이미 답을 가지고 있지만 더 깨끗하고 자세하게 만들려고 노력했습니다.
데이터는 다음과 같습니다
d <- structure(list(Name = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L,
3L, 3L), .Label = c("Aira", "Ben", "Cat"), class = "factor"),
Month = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), Rate1 = c(12L,
18L, 19L, 53L, 22L, 19L, 22L, 67L, 45L), Rate2 = c(23L, 73L,
45L, 19L, 87L, 45L, 87L, 43L, 32L)), .Names = c("Name", "Month",
"Rate1", "Rate2"), class = "data.frame", row.names = c(NA, -9L
))
head(d)
Name Month Rate1 Rate2
1 Aira 1 12 23
2 Aira 2 18 73
3 Aira 3 19 45
4 Ben 1 53 19
5 Ben 2 22 87
6 Ben 3 19 45
library("reshape2")
mym <- melt(d, id = c("Name"))
res <- dcast(mym, Name ~ variable, mean)
res
#Name Month Rate1 Rate2
#1 Aira 2 16.33333 47.00000
#2 Ben 2 31.33333 50.33333
#3 Cat 2 44.66667 54.00000
data.table 사용 :
# At first, I convert the data.frame to data.table and then I group it
setDT(d)
d[, .(Rate1 = mean(Rate1), Rate2 = mean(Rate2)), by = .(Name)]
# Name Rate1 Rate2
#1: Aira 16.33333 47.00000
#2: Ben 31.33333 50.33333
#3: Cat 44.66667 54.00000
.SD를 사용하여 data.table에 j에 대한 많은 인수를 쓰지 않고 다른 방법이 있습니다.
d[, lapply(.SD, mean), by = .(Name)]
# Name Month Rate1 Rate2
#1: Aira 2 16.33333 47.00000
#2: Ben 2 31.33333 50.33333
#3: Cat 2 44.66667 54.00000
Rate1과 Rate2 만 갖고 싶다면 다음과 같이 .SDcol 을 사용할 수 있습니다 .
d[, lapply(.SD, mean), by = .(Name), .SDcols = 3:4]
# Name Rate1 Rate2
#1: Aira 16.33333 47.00000
#2: Ben 31.33333 50.33333
#3: Cat 44.66667 54.00000
R
대체 aggregate
방법을 포함하여 기본적 으로이를 수행하는 다양한 방법이 있습니다. 아래의 예는 매월 의미하며 귀하가 요청한 것입니다. 그러나 동일한 접근 방식을 사용하여 1 인당 수단을 반환 할 수 있습니다.
사용 ave
:
my.data <- read.table(text = '
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
Rate1.mean <- with(my.data, ave(Rate1, Month, FUN = function(x) mean(x, na.rm = TRUE)))
Rate2.mean <- with(my.data, ave(Rate2, Month, FUN = function(x) mean(x, na.rm = TRUE)))
my.data <- data.frame(my.data, Rate1.mean, Rate2.mean)
my.data
사용 by
:
my.data <- read.table(text = '
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
by.month <- as.data.frame(do.call("rbind", by(my.data, my.data$Month, FUN = function(x) colMeans(x[,3:4]))))
colnames(by.month) <- c('Rate1.mean', 'Rate2.mean')
by.month <- cbind(Month = rownames(by.month), by.month)
my.data <- merge(my.data, by.month, by = 'Month')
my.data
사용 lapply
하여 split
:
my.data <- read.table(text = '
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
ly.mean <- lapply(split(my.data, my.data$Month), function(x) c(Mean = colMeans(x[,3:4])))
ly.mean <- as.data.frame(do.call("rbind", ly.mean))
ly.mean <- cbind(Month = rownames(ly.mean), ly.mean)
my.data <- merge(my.data, ly.mean, by = 'Month')
my.data
사용 sapply
하여 split
:
my.data <- read.table(text = '
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
my.data
sy.mean <- t(sapply(split(my.data, my.data$Month), function(x) colMeans(x[,3:4])))
colnames(sy.mean) <- c('Rate1.mean', 'Rate2.mean')
sy.mean <- data.frame(Month = rownames(sy.mean), sy.mean, stringsAsFactors = FALSE)
my.data <- merge(my.data, sy.mean, by = 'Month')
my.data
사용 aggregate
:
my.data <- read.table(text = '
Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32
', header = TRUE, stringsAsFactors = FALSE, na.strings = 'NA')
my.summary <- with(my.data, aggregate(list(Rate1, Rate2), by = list(Month),
FUN = function(x) { mon.mean = mean(x, na.rm = TRUE) } ))
my.summary <- do.call(data.frame, my.summary)
colnames(my.summary) <- c('Month', 'Rate1.mean', 'Rate2.mean')
my.summary
my.data <- merge(my.data, my.summary, by = 'Month')
my.data
You could also use the generic function cbind()
and lm()
without the intercept:
cbind(lm(d$Rate1~-1+d$Name)$coef,lm(d$Rate2~-1+d$Name)$coef)
> [,1] [,2]
>d$NameAira 16.33333 47.00000
>d$NameBen 31.33333 50.33333
>d$NameCat 44.66667 54.00000
You can also accomplish this using the sqldf
package as shown below:
library(sqldf)
x <- read.table(text='Name Month Rate1 Rate2
Aira 1 12 23
Aira 2 18 73
Aira 3 19 45
Ben 1 53 19
Ben 2 22 87
Ben 3 19 45
Cat 1 22 87
Cat 2 67 43
Cat 3 45 32', header=TRUE)
sqldf("
select
Name
,avg(Rate1) as Rate1_float
,avg(Rate2) as Rate2_float
,avg(Rate1) as Rate1
,avg(Rate2) as Rate2
from x
group by
Name
")
# Name Rate1_float Rate2_float Rate1 Rate2
#1 Aira 16.33333 47.00000 16 47
#2 Ben 31.33333 50.33333 31 50
#3 Cat 44.66667 54.00000 44 54
I am a recent convert to dplyr
as shown in other answers, but sqldf
is nice as most data analysts/data scientists/developers have at least some fluency in SQL. In this way, I think it tends to make for more universally readable code than dplyr
or other solutions presented above.
UPDATE: In responding to the comment below, I attempted to update the code as shown above. However, the behavior was not as I expected. It seems that the column definition (i.e. int
vs float
) is only carried through when the column alias matches the original column name. When you specify a new name, the aggregate column is returned without rounding.
참고URL : https://stackoverflow.com/questions/21982987/mean-per-group-in-a-data-frame
'Programing' 카테고리의 다른 글
클릭 탭시 쉘 초기화 문제, getcwd의 문제점은 무엇입니까? (0) | 2020.06.19 |
---|---|
matplotlib : 선의 개별 점에 대한 마커를 설정합니다 (0) | 2020.06.18 |
논리적 조건으로 data.frame 행 필터링 (0) | 2020.06.18 |
외부에서 도커 컨테이너의 PostgreSQL에 연결 (0) | 2020.06.18 |
브라우저의 뷰포트를 기준으로 요소의 최상위 위치를 얻는 방법은 무엇입니까? (0) | 2020.06.18 |