이 게시물에 대한 (매우 훌륭한) 답변 by
과 aggregate
설명 이 없음을 깨달았습니다 . 여기 내 공헌이 있습니다.
으로
by
로 문서에 명시된 기능을위한 "래퍼"로,하지만 될 수 있습니다 tapply
. 처리 할 수없는 by
작업을 계산하려고 할 때 의 힘이 발생합니다 tapply
. 한 가지 예는 다음 코드입니다.
ct <- tapply(iris$Sepal.Width , iris$Species , summary )
cb <- by(iris$Sepal.Width , iris$Species , summary )
cb
iris$Species: setosa
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.300 3.200 3.400 3.428 3.675 4.400
--------------------------------------------------------------
iris$Species: versicolor
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.000 2.525 2.800 2.770 3.000 3.400
--------------------------------------------------------------
iris$Species: virginica
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.200 2.800 3.000 2.974 3.175 3.800
ct
$setosa
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.300 3.200 3.400 3.428 3.675 4.400
$versicolor
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.000 2.525 2.800 2.770 3.000 3.400
$virginica
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.200 2.800 3.000 2.974 3.175 3.800
우리가이 두 개체를 인쇄하는 경우 ct
와 cb
, 우리는 "기본적으로"동일한 결과를 유일한 차이는 그들이 어떻게 표시되고 다른에있는 class
각각의 속성 by
에 대한 cb
및 array
대한 ct
.
내가 말했듯이, by
우리가 사용할 수 없을 때 의 힘이 생깁니다 tapply
. 다음 코드는 한 가지 예입니다.
tapply(iris, iris$Species, summary )
Error in tapply(iris, iris$Species, summary) :
arguments must have same length
R은 인수의 길이가 같아야한다고 말합니다. "인수 summary
를 iris
따라 모든 변수 를 계산하고 싶습니다 Species
": R은 처리 방법을 모르기 때문에 그렇게 할 수 없습니다.
by
함수 R을 사용하면 data frame
클래스에 대한 특정 메소드를 전달한 다음 summary
첫 번째 인수의 길이 (및 유형도)가 다른 경우에도 함수가 작동하게합니다.
bywork <- by(iris, iris$Species, summary )
bywork
iris$Species: setosa
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 versicolor: 0
Median :5.000 Median :3.400 Median :1.500 Median :0.200 virginica : 0
Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246
3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300
Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600
--------------------------------------------------------------
iris$Species: versicolor
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 setosa : 0
1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 versicolor:50
Median :5.900 Median :2.800 Median :4.35 Median :1.300 virginica : 0
Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326
3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500
Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800
--------------------------------------------------------------
iris$Species: virginica
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400 setosa : 0
1st Qu.:6.225 1st Qu.:2.800 1st Qu.:5.100 1st Qu.:1.800 versicolor: 0
Median :6.500 Median :3.000 Median :5.550 Median :2.000 virginica :50
Mean :6.588 Mean :2.974 Mean :5.552 Mean :2.026
3rd Qu.:6.900 3rd Qu.:3.175 3rd Qu.:5.875 3rd Qu.:2.300
Max. :7.900 Max. :3.800 Max. :6.900 Max. :2.500
실제로 작동하며 결과는 매우 놀랍습니다. 이 클래스의 목적 by
에 따라 그 Species
(예를 들어, 그들 각각에 대해)를 계산하는 summary
각 변수를.
첫 번째 인수가 data frame
인 경우 전달 된 함수에는 해당 객체 클래스에 대한 메소드가 있어야합니다. 예를 들어이 mean
코드를 전혀 이해하지 못하는 함수 와 함께 사용하는 것입니다.
by(iris, iris$Species, mean)
iris$Species: setosa
[1] NA
-------------------------------------------
iris$Species: versicolor
[1] NA
-------------------------------------------
iris$Species: virginica
[1] NA
Warning messages:
1: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
2: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
3: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
골재
aggregate
tapply
우리가 그런 식으로 사용 한다면 또 다른 사용 방법으로 볼 수 있습니다 .
at <- tapply(iris$Sepal.Length , iris$Species , mean)
ag <- aggregate(iris$Sepal.Length , list(iris$Species), mean)
at
setosa versicolor virginica
5.006 5.936 6.588
ag
Group.1 x
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
두 즉시 차이는 두 번째 인자가되어 aggregate
있어야 하는 동안 목록이 tapply
CAN (필수 생략)리스트하고 출력이 그 aggregate
중 하나가 동시에 데이터 프레임 tapply
이다 array
.
이것의 aggregate
장점은 subset
인수로 데이터의 하위 집합을 쉽게 처리 할 수 있으며 ts
개체 및 메서드에 대한 메서드가 있다는 것 formula
입니다.
이러한 요소 는 일부 상황에서 aggregate
보다 쉽게 작업 할 수 tapply
있습니다. 다음은 몇 가지 예입니다 (문서에서 사용 가능).
ag <- aggregate(len ~ ., data = ToothGrowth, mean)
ag
supp dose len
1 OJ 0.5 13.23
2 VC 0.5 7.98
3 OJ 1.0 22.70
4 VC 1.0 16.77
5 OJ 2.0 26.06
6 VC 2.0 26.14
우리는 같은 것을 달성 할 수 tapply
있지만 구문은 약간 어렵고 출력 (일부 상황에서는)을 읽을 수 없습니다.
att <- tapply(ToothGrowth$len, list(ToothGrowth$dose, ToothGrowth$supp), mean)
att
OJ VC
0.5 13.23 7.98
1 22.70 16.77
2 26.06 26.14
이 우리가 사용할 수없는 다른 배 by
또는 tapply
우리가 사용해야합니다 aggregate
.
ag1 <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, mean)
ag1
Month Ozone Temp
1 5 23.61538 66.73077
2 6 29.44444 78.22222
3 7 59.11538 83.88462
4 8 59.96154 83.96154
5 9 31.44828 76.89655
tapply
한 번의 호출로 이전 결과를 얻을 수는 없지만 Month
각 요소 의 평균을 계산 한 다음 결합해야합니다 ( 함수 na.rm = TRUE
의 formula
메소드는 aggregate
기본적 으로을 갖기 때문에을 호출해야 함 na.action = na.omit
).
ta1 <- tapply(airquality$Ozone, airquality$Month, mean, na.rm = TRUE)
ta2 <- tapply(airquality$Temp, airquality$Month, mean, na.rm = TRUE)
cbind(ta1, ta2)
ta1 ta2
5 23.61538 65.54839
6 29.44444 79.10000
7 59.11538 83.90323
8 59.96154 83.96774
9 31.44828 76.90000
그러나 by
실제로 다음 함수 호출은 오류를 반환합니다 (그러나 대부분 제공된 함수와 관련이 있습니다 mean
).
by(airquality[c("Ozone", "Temp")], airquality$Month, mean, na.rm = TRUE)
다른 경우에는 결과가 동일하고 차이점은 클래스에 있습니다 (그리고 그 결과가 어떻게 하위 세트로 표시 되는가뿐만 아니라 표시 / 인쇄되는 방식).
byagg <- by(airquality[c("Ozone", "Temp")], airquality$Month, summary)
aggagg <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, summary)
앞의 코드는 동일한 목표와 결과를 얻습니다. 어떤 시점에서 사용할 도구는 개인적인 취향과 요구의 문제입니다. 앞의 두 객체는 서브 셋팅 측면에서 매우 다른 요구를 가지고 있습니다.
*apply()
and를 직접 대체합니다by
. plyr (적어도 나에게)는 내가 기대하는 데이터 형식과 정확히 어떤 데이터가 튀어 나올지 항상 알고 있다는 점에서 훨씬 일관성이있는 것 같습니다. 그것은 많은 번거 로움을 덜어줍니다.