그룹화 기능(적용, 기준, 집계) 및 *적용 제품군
제가 R에서 "맵" 파이를 하고 싶을 때마다, 저는 보통 R에서 함수를 사용하려고 노력합니다.apply
가족.
하지만, 저는 그들 사이의 차이점을 제대로 이해하지 못했습니다. 어떻게 {}sapply
,lapply
etc/그룹화된 , 에 대해서도 합니다. 그래서을 얻을 .}은(는) 입력/그룹화된 입력, 출력이 어떻게 보일지, 심지어 입력이 무엇인지에 대해서도 함수를 적용합니다. 그래서 저는 종종 원하는 것을 얻을 때까지 모든 것을 거칩니다.
어떤 것을 언제 사용하는지 누가 설명해 줄 수 있나요?
현재 제가 이해하고 있는 것은...
sapply(vec, f)
입이벡다니터입matrix. 은 벡터/벡터로, 서 요소는 출은/이며, 여서요입니다.i
이라f(vec[i])
합니다.f
을 가지고 .lapply(vec, f)
과 같은sapply
하지만 출력은 목록입니까?apply(matrix, 1/2, f)
입력이 행렬입니다.출력은 벡터이며, 여기서 요소는i
f) is f(행렬의 행/대장균)tapply(vector, grouping, f)
는 출은행배/열이며배, 여서행렬/열의요다값의 입니다.f
g
, 그의, 고리고.g
names "/"에.by(dataframe, grouping, f)
셋방살이g
그룹화를 적용합니다. 적용합니다.f
그룹/데이터 프레임의 각 열로 이동합니다.그룹화와 가치를 예쁘게 인쇄합니다.f
각 란에aggregate(matrix, grouping, f)
와비한과 한.by
그러나 출력물을 예쁘게 인쇄하는 대신 Aggregate는 모든 것을 데이터 프레임에 고정합니다.
측면 질문:저는 아직 플라이어나 모양 바꾸기를 배우지 못했습니다.plyr
또는reshape
이 모든 것을 완전히 대체할 수 있습니까?
할 수 있는 *apply 이 많이 있습니다( R적많예이있기습니 *다능이설된용도움말명파일에는에예▁which적(있:습).?apply
에, 처음 은 어떤 에 적합한지 그것들을 모두 하는 데 을 겪을 수 있습니다 그러나 초기 사용자들은 어떤 것이 자신의 상황에 적합한지를 결정하거나 심지어 모두 기억하는 데 어려움을 겪을 수 있습니다.이들은 "여기에 *적용 기능을 사용해야 한다"는 일반적인 감각을 가지고 있을 수 있지만, 처음에는 모든 기능을 똑바로 유지하는 것이 어려울 수 있습니다.
중 상당 이 매우 있는 *apply 제품군에 있음에도 됨)plyr
패키지, 기본 기능은 유용하고 알 가치가 있습니다.
이 답변은 새로운 userR이 특정 문제에 대해 올바른 *적용 기능을 사용할 수 있도록 안내하는 일종의 표지판 역할을 하기 위한 것입니다.참고로, 이것은 단순히 R 문서를 반복하거나 대체하기 위한 것이 아닙니다!희망 사항은 이 답변이 귀하의 상황에 맞는 *적용 기능을 결정하는 데 도움이 될 것이며, 이를 추가로 조사하는 것은 귀하에게 달려 있습니다.한 가지 예외를 제외하고는 성능 차이는 해결되지 않습니다.
apply - 함수를 행렬의 행 또는 열(및 고차원 아날로그)에 적용하려는 경우, 행렬에 먼저 강제 적용되므로 일반적으로 데이터 프레임에는 권장되지 않습니다.
# Two dimensional matrix M <- matrix(seq(1,16), 4, 4) # apply min to rows apply(M, 1, min) [1] 1 2 3 4 # apply max to columns apply(M, 2, max) [1] 4 8 12 16 # 3 dimensional array M <- array( seq(32), dim = c(4,4,2)) # Apply sum across each M[*, , ] - i.e Sum across 2nd and 3rd dimension apply(M, 1, sum) # Result is one-dimensional [1] 120 128 136 144 # Apply sum across each M[*, *, ] - i.e Sum across 3rd dimension apply(M, c(1,2), sum) # Result is two-dimensional [,1] [,2] [,3] [,4] [1,] 18 26 34 42 [2,] 20 28 36 44 [3,] 22 30 38 46 [4,] 24 32 40 48
행렬에 열 평균 경우, 최적화되고 처럼 빠른 2D를 .
colMeans
,rowMeans
,colSums
,rowSums
.lapply - 목록의 각 요소에 함수를 차례로 적용하고 목록을 다시 가져오려는 경우.
이 기능은 다른 *적용 기능의 대부분을 차지합니다.그들의 코드를 벗겨내면 종종 발견될 것입니다.
lapply
밑에x <- list(a = 1, b = 1:3, c = 10:100) lapply(x, FUN = length) $a [1] 1 $b [1] 3 $c [1] 91 lapply(x, FUN = sum) $a [1] 1 $b [1] 6 $c [1] 5005
sapply - 목록의 각 요소에 함수를 차례로 적용하고 싶지만 목록이 아닌 벡터를 원하는 경우.
이 타이핑하는 한다면,
unlist(lapply(...))
생각해 .sapply
.x <- list(a = 1, b = 1:3, c = 10:100) # Compare with above; a named vector, not a list sapply(x, FUN = length) a b c 1 3 91 sapply(x, FUN = sum) a b c 1 6 5005
보다 고급적인 용도로 사용되는 경우
sapply
적절한 경우 결과를 다차원 배열로 강제하려고 시도합니다.예를 들어, 만약 우리의 함수가 같은 길이의 벡터를 반환한다면,sapply
로 사용합니다. 행렬: " " " " 값 " 합 " 니 " 용 " 다 " 사 " 이 " 을 " 로 " 열 " 행 렬 "sapply(1:5,function(x) rnorm(3,x))
의 함수가 행렬인 만약차우 2차원 행렬을 한다면,
sapply
반환된 각 행렬을 하나의 긴 벡터로 처리하여 기본적으로 동일한 작업을 수행합니다.sapply(1:5,function(x) matrix(x,2,2))
가 지정하지 않는 한.
simplify = "array"
배열을 합니다: 경 우 개 행 사 여 다 배 구 합 성 니 을 다 열 원 이 차 하 용 별 렬 을 니 합 다 ▁in 구 성 : 이 배 ▁to 을 ▁it ▁a ▁will ▁thesapply(1:5,function(x) matrix(x,2,2), simplify = "array")
이러한 각 동작은 물론 길이 또는 차원이 같은 벡터 또는 행렬을 반환하는 함수에 따라 달라집니다.
vapply - 사용하고 싶지만 코드에서 속도를 더 내야 하거나 더 많은 유형의 안전을 원할 때 사용합니다.
위해서
vapply
기본적으로 R에게 함수가 반환할 종류의 예를 제공하여 반환된 값을 단일 원자 벡터에 맞도록 강제하는 시간을 절약할 수 있습니다.x <- list(a = 1, b = 1:3, c = 10:100) #Note that since the advantage here is mainly speed, this # example is only for illustration. We're telling R that # everything returned by length() should be an integer of # length 1. vapply(x, FUN = length, FUN.VALUE = 0L) a b c 1 3 91
매플리 - 여러 데이터 구조(예: 벡터, 목록)가 있는 경우 각 데이터 구조의 첫 번째 요소에 함수를 적용한 다음 각 요소의 두 번째 요소 등에 함수를 적용하여 결과를 의 벡터/어레이에 강제로 적용하려는 경우에 사용합니다.
이것은 함수가 다중 인수를 수용해야 한다는 의미에서 다변량입니다.
#Sums the 1st elements, the 2nd elements, etc. mapply(sum, 1:5, 1:5, 1:5) [1] 3 6 9 12 15 #To do rep(1,4), rep(2,3), etc. mapply(rep, 1:4, 4:1) [[1]] [1] 1 1 1 1 [[2]] [1] 2 2 2 [[3]] [1] 3 3 [[4]] [1] 4
지도 - 목록을 반환하도록 보장되는 로의 래퍼입니다.
Map(sum, 1:5, 1:5, 1:5) [[1]] [1] 3 [[2]] [1] 6 [[3]] [1] 9 [[4]] [1] 12 [[5]] [1] 15
래플리 - 중첩된 리스트 구조의 각 요소에 함수를 재귀적으로 적용하려는 경우에 사용합니다.
당신에게 얼마나 흔하지 않은지에 대해 알려주는 것.
rapply
제가처 이올답때릴있다니었습잊 물론 당연히 많은 분들이 쓰시겠지만 YMMV.rapply
적용할 사용자 정의 기능이 가장 잘 설명되어 있습니다.# Append ! to string, otherwise increment myFun <- function(x){ if(is.character(x)){ return(paste(x,"!",sep="")) } else{ return(x + 1) } } #A nested list structure l <- list(a = list(a1 = "Boo", b1 = 2, c1 = "Eeek"), b = 3, c = "Yikes", d = list(a2 = 1, b2 = list(a3 = "Hey", b3 = 5))) # Result is named vector, coerced to character rapply(l, myFun) # Result is a nested list like l, with values altered rapply(l, myFun, how="replace")
태플리 - 벡터의 부분 집합에 함수를 적용하고 부분 집합이 다른 벡터(일반적으로 요인)에 의해 정의되는 경우에 사용합니다.
*적용 가족의 흑양, 일종의.도움말 파일에서 "ragged array"라는 문구를 사용하는 것은 다소 혼란스러울 수 있지만 실제로는 매우 간단합니다.
벡터:
x <- 1:20
그룹을 정의하는 요인(같은 길이의 요인!):
y <- factor(rep(letters[1:5], each = 4))
다니합의 합니다.
x
의 정된 각부내로 된 각y
:tapply(x, y, sum) a b c d e 10 26 42 58 74
부분군이 여러 요인 리스트의 고유한 조합으로 정의되는 경우 더 복잡한 예제를 처리할 수 있습니다.
tapply
R에서 공통적으로 사용되는 분할-적용-결합 함수와 정신적으로 유사합니다(aggregate
,by
,ave
,ddply
등) 따라서 흑양의 지위.
참고로, 여기 다양한 방법이 있습니다.plyr
기에해저수는함하에 합니다.*apply
functions (plyr 웹페이지 http://had.co.nz/plyr/) 의 소개 문서에서)
Base function Input Output plyr function
---------------------------------------
aggregate d d ddply + colwise
apply a a/l aaply / alply
by d l dlply
lapply l l llply
mapply a a/l maply / mlply
replicate r a/l raply / rlply
sapply l a laply
의 목표 중 plyr
는 각 함수에 대해 일관된 명명 규칙을 제공하여 함수 이름에 입력 및 출력 데이터 유형을 인코딩합니다.또한 출력의 일관성을 제공합니다.dlply()
쉽게 전달할 수 있습니다.ldply()
유용한 산출물 등을 생산하기 위해
배우는 은 습학으로, 개념적입니다.plyr
.*apply
기능들.
plyr
그리고.reshape
기능은 제 일상적인 사용에서 거의 모든 기능을 대체했습니다.그러나 Plyr 소개 문서에서도 다음과 같이 설명합니다.
기능 관련함수
tapply
그리고.sweep
에 .plyr
유용하게 사용할 수 있습니다.merge
요약을 원본 데이터와 결합하는 데 유용합니다.
http://www.slideshare.net/hadley/plyr-one-data-analytic-strategy 의 슬라이드 21에서:
요, 확한것은바대실건라▁(바.apply
@ @Hadley's 당합니다해에합니다.aaply
그리고.aggregate
@ @Hadley's 당합니다해에합니다.ddply
기타. 이 이미지에서 얻을 수 없는 경우 동일한 슬라이드 공유의 슬라이드 20이 명확합니다.)
(왼쪽은 입력, 위는 출력)
먼저 조란의 훌륭한 답변으로 시작합니다. 무엇이든 그것보다 더 좋을 수 있을지 의심스럽습니다.
그런 다음 다음 니모닉은 각각의 차이를 기억하는 데 도움이 될 수 있습니다.일부는 분명하지만, 다른 일부는 덜 그럴 수도 있습니다. 이것들은 조란의 토론에서 정당성을 찾을 수 있습니다.
니모닉
lapply
목록 또는 벡터에 작용하고 목록을 반환하는 목록 적용입니다.sapply
단순한lapply
을 반환하는 으로 기본 설정됨 ("함수"는 벡터나 행렬을 반환합니다.vapply
검증된 적용입니다(반복 객체 유형을 사전 지정해야 합니다.rapply
중첩된 목록, 즉 목록 내 목록에 대한 재귀적 적용입니다.tapply
태그가 하위 집합을 식별하는 태그 적용입니다.apply
일반: 행렬의 행 또는 열(또는 더 일반적으로 배열의 차원)에 함수를 적용합니다.
올바른 배경 구축
를 apply
가족은 여전히 당신에게 약간 이질적이라고 생각합니다, 그렇다면 당신이 핵심적인 관점을 놓치고 있는 것일 수도 있습니다.
이 두 기사가 도움이 될 수 있습니다.그들은 기능적 프로그래밍 기술에 동기를 부여하는 데 필요한 배경을 제공합니다.apply
함수의 집합
리스프 사용자는 즉시 패러다임을 인식할 것입니다.만약 당신이 리스프에 익숙하지 않다면, 일단 당신이 FP에 대해 머리를 쓰면, 당신은 R에서 사용할 수 있는 강력한 관점을 얻게 될 것입니다.apply
훨씬 더 말이 될 겁니다
는 이 한) 것을 때문입니다.by
그리고.aggregate
◦한 바가 .이것이 제 공헌입니다.
타고
그by
처럼 함수는 "준한에"의 "wrapper될 수 .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
를 한 the 업하고내둬려버나서수▁the.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
dispatched 함수에는 해당 클래스의 개체에 대한 메서드가 있어야 합니다.를 들어, 는 이 를 예를들어다, 같사를이용다니합음과와 함께 사용합니다.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
(필수가 아님) 목록이 될 수 있으며 의 출력은aggregate
는 데이터 프레임인 반면에 다음 중 하나입니다.tapply
입니다.array
.
의의 힘 aggregate
, 데터 하집쉽 처수있다습으로 집합을 할 수 .subset
이▁for에 대한 방법을 가지고 입니다.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
함수한다는 것을 수 . (이 높은 인 우는사다함호것반그달을수없다성니습할는다것환다러리아있니입관함을제이련와수된공그한오마것은도류나를출수이실음그▁(▁we▁call▁returns,▁(but▁that▁in▁it▁an▁can▁just▁following▁error다▁function▁likely▁most▁supplied'▁function▁the니것▁achievet▁the▁fact▁related.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
함수가 측정되지 않습니다.
는 두 했습니다.sum
그리고.length
된 시 시 입니다.테스트된 볼륨은 입력 시 50M, 출력 시 50K입니다. 두 현재 인기 있는 인 질이있을당개시널에는리문사다않니패있 2포습했함도지키는인기현을 했습니다.data.table
그리고.dplyr
좋은 성과를 목표로 한다면 두 가지 모두 분명히 볼 가치가 있습니다.
library(dplyr)
library(data.table)
set.seed(123)
n = 5e7
k = 5e5
x = runif(n)
grp = sample(k, n, TRUE)
timing = list()
# sapply
timing[["sapply"]] = system.time({
lt = split(x, grp)
r.sapply = sapply(lt, function(x) list(sum(x), length(x)), simplify = FALSE)
})
# lapply
timing[["lapply"]] = system.time({
lt = split(x, grp)
r.lapply = lapply(lt, function(x) list(sum(x), length(x)))
})
# tapply
timing[["tapply"]] = system.time(
r.tapply <- tapply(x, list(grp), function(x) list(sum(x), length(x)))
)
# by
timing[["by"]] = system.time(
r.by <- by(x, list(grp), function(x) list(sum(x), length(x)), simplify = FALSE)
)
# aggregate
timing[["aggregate"]] = system.time(
r.aggregate <- aggregate(x, list(grp), function(x) list(sum(x), length(x)), simplify = FALSE)
)
# dplyr
timing[["dplyr"]] = system.time({
df = data_frame(x, grp)
r.dplyr = summarise(group_by(df, grp), sum(x), n())
})
# data.table
timing[["data.table"]] = system.time({
dt = setnames(setDT(list(x, grp)), c("x","grp"))
r.data.table = dt[, .(sum(x), .N), grp]
})
# all output size match to group count
sapply(list(sapply=r.sapply, lapply=r.lapply, tapply=r.tapply, by=r.by, aggregate=r.aggregate, dplyr=r.dplyr, data.table=r.data.table),
function(x) (if(is.data.frame(x)) nrow else length)(x)==k)
# sapply lapply tapply by aggregate dplyr data.table
# TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# print timings
as.data.table(sapply(timing, `[[`, "elapsed"), keep.rownames = TRUE
)[,.(fun = V1, elapsed = V2)
][order(-elapsed)]
# fun elapsed
#1: aggregate 109.139
#2: by 25.738
#3: dplyr 18.978
#4: tapply 17.006
#5: lapply 11.524
#6: sapply 11.326
#7: data.table 2.686
있는 모든 두 더. 한 기능인 있모개답불구고하도변에여다가있언급, 치가기는기본능있이 2더습니에할기는든훌륭한▁despite▁that개▁the다▁useful▁more▁functions있니▁base▁there,,▁here▁2. 유용합니다.outer
한 무명과능기▁function.eapply
를 수행
바깥쪽의
outer
더 평범한 기능으로 숨겨져 있는 매우 유용한 기능입니다.다음에 대한 도움말을 읽는 경우outer
그것의 설명은 다음과 같습니다.
The outer product of the arrays X and Y is the array A with dimension
c(dim(X), dim(Y)) where element A[c(arrayindex.x, arrayindex.y)] =
FUN(X[arrayindex.x], Y[arrayindex.y], ...).
이것은 선형 대수학 유형의 것들에만 유용한 것처럼 보이게 합니다.그러나, 그것은 다음과 같이 사용될 수 있습니다.mapply
두 입력 벡터에 함수를 적용합니다.은 다른점은입니다.mapply
의 두 하고, 의 두 요소에 기능을 에, 함를 처 두 음 요 적 반 등 요 적 에 합 니 용 면 다 소 두 수 음 다outer
첫 번째 벡터와 두 번째 벡터의 모든 요소 조합에 함수를 적용합니다.예:
A<-c(1,3,5,7,9)
B<-c(0,3,6,9,12)
mapply(FUN=pmax, A, B)
> mapply(FUN=pmax, A, B)
[1] 1 3 6 9 12
outer(A,B, pmax)
> outer(A,B, pmax)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 6 9 12
[2,] 3 3 6 9 12
[3,] 5 5 6 9 12
[4,] 7 7 7 9 12
[5,] 9 9 9 9 12
저는 개인적으로 값의 벡터와 조건의 벡터를 가지고 있고 어떤 값이 어떤 조건을 충족하는지 알고 싶을 때 이것을 사용했습니다.
이플리
eapply
는 것과 같은lapply
목록의 모든 요소에 함수를 적용하는 대신 환경의 모든 요소에 함수를 적용합니다.예를 들어 글로벌 환경에서 사용자 정의 함수 목록을 찾으려는 경우:
A<-c(1,3,5,7,9)
B<-c(0,3,6,9,12)
C<-list(x=1, y=2)
D<-function(x){x+1}
> eapply(.GlobalEnv, is.function)
$A
[1] FALSE
$B
[1] FALSE
$C
[1] FALSE
$D
[1] TRUE
솔직히 나는 이것을 잘 사용하지 않지만, 만약 당신이 많은 패키지를 만들거나 많은 환경을 만든다면 그것은 도움이 될 것입니다.
그것은 아마 언급할 가치가 있을 것입니다.ave
.ave
이라tapply
할 수 합니다.데이터 프레임에 직접 연결할 수 있는 형태로 결과를 반환합니다.
dfr <- data.frame(a=1:20, f=rep(LETTERS[1:5], each=4))
means <- tapply(dfr$a, dfr$f, mean)
## A B C D E
## 2.5 6.5 10.5 14.5 18.5
## great, but putting it back in the data frame is another line:
dfr$m <- means[dfr$f]
dfr$m2 <- ave(dfr$a, dfr$f, FUN=mean) # NB argument name FUN is needed!
dfr
## a f m m2
## 1 A 2.5 2.5
## 2 A 2.5 2.5
## 3 A 2.5 2.5
## 4 A 2.5 2.5
## 5 B 6.5 6.5
## 6 B 6.5 6.5
## 7 B 6.5 6.5
## ...
에는 기본패에다같음작것없습다니처럼 작동하는 .ave
프레임에 (전체데터프에대한임레이대한▁for에)by
는 것과 같은tapply
데이터 프레임의 경우).하지만 당신은 그것을 속일 수 있습니다.
dfr$foo <- ave(1:nrow(dfr), dfr$f, FUN=function(x) {
x <- dfr[x,]
sum(x$m*x$m2)
})
dfr
## a f m m2 foo
## 1 1 A 2.5 2.5 25
## 2 2 A 2.5 2.5 25
## 3 3 A 2.5 2.5 25
## ...
나는 최근에 꽤 유용한 것을 발견했습니다.sweep
완전성을 위해 기능하고 여기에 추가합니다.
쓸다
기본 아이디어는 배열을 행 단위 또는 열 단위로 스위프하고 수정된 배열을 반환하는 것입니다.예를 들어 다음과 같이 확인할 수 있습니다(출처: 데이터캠프).amp).
행렬이 있고 행렬을 열 단위로 표준화하려고 합니다.
dataPoints <- matrix(4:15, nrow = 4)
# Find means per column with `apply()`
dataPoints_means <- apply(dataPoints, 2, mean)
# Find standard deviation with `apply()`
dataPoints_sdev <- apply(dataPoints, 2, sd)
# Center the points
dataPoints_Trans1 <- sweep(dataPoints, 2, dataPoints_means,"-")
# Return the result
dataPoints_Trans1
## [,1] [,2] [,3]
## [1,] -1.5 -1.5 -1.5
## [2,] -0.5 -0.5 -0.5
## [3,] 0.5 0.5 0.5
## [4,] 1.5 1.5 1.5
# Normalize
dataPoints_Trans2 <- sweep(dataPoints_Trans1, 2, dataPoints_sdev, "/")
# Return the result
dataPoints_Trans2
## [,1] [,2] [,3]
## [1,] -1.1618950 -1.1618950 -1.1618950
## [2,] -0.3872983 -0.3872983 -0.3872983
## [3,] 0.3872983 0.3872983 0.3872983
## [4,] 1.1618950 1.1618950 1.1618950
NB이 동일한 결과를 더 수 .
apply(dataPoints, 2, scale)
최근 CRAN에 공개된 축소 패키지에서 저는 대부분의 일반적인 적용 기능을 단 두 가지 기능으로 압축하려고 시도했습니다.
dapply
data.의 행 각인 경우 및 (Data-Apply) (Data-Apply) 데이터.frames는 (데이터 적용) 입니다).drop = TRUE
)와 비슷한 성능은 다음과 같습니다.lapply
열의 , data.frame보다 약 더 .apply
행렬 행 또는 열의 경우.병렬 처리는 다음을 통해 사용할 수 있습니다.mclapply
(MAC에만 해당).
구문:
dapply(X, FUN, ..., MARGIN = 2, parallel = FALSE, mc.cores = 1L,
return = c("same", "matrix", "data.frame"), drop = TRUE)
예:
# Apply to columns:
dapply(mtcars, log)
dapply(mtcars, sum)
dapply(mtcars, quantile)
# Apply to rows:
dapply(mtcars, sum, MARGIN = 1)
dapply(mtcars, quantile, MARGIN = 1)
# Return as matrix:
dapply(mtcars, quantile, return = "matrix")
dapply(mtcars, quantile, MARGIN = 1, return = "matrix")
# Same for matrices ...
BY
는 벡터, 매트릭스 및 data.frame 메서드를 사용하는 분할 적용 결합 컴퓨팅을 위한 S3 일반형입니다.은 보다훨빠다릅니씬다니릅빠▁than보다 훨씬 빠릅니다.tapply
,by
그리고.aggregate
( (보다)plyr
에 대해dplyr
더 빠르긴 하지만).
구문:
BY(X, g, FUN, ..., use.g.names = TRUE, sort = TRUE,
expand.wide = FALSE, parallel = FALSE, mc.cores = 1L,
return = c("same", "matrix", "data.frame", "list"))
예:
# Vectors:
BY(iris$Sepal.Length, iris$Species, sum)
BY(iris$Sepal.Length, iris$Species, quantile)
BY(iris$Sepal.Length, iris$Species, quantile, expand.wide = TRUE) # This returns a matrix
# Data.frames
BY(iris[-5], iris$Species, sum)
BY(iris[-5], iris$Species, quantile)
BY(iris[-5], iris$Species, quantile, expand.wide = TRUE) # This returns a wider data.frame
BY(iris[-5], iris$Species, quantile, return = "matrix") # This returns a matrix
# Same for matrices ...
은 그화변목다제수있도다니습할공음에룹에 제공될 .g
.
성능에 대해 말씀드리겠습니다.붕괴의 주요 목표는 R에서 고성능 프로그래밍을 육성하고 분할 적용 결합을 넘어서는 것입니다.이를 위해 패키지에는 C++ 기반 고속 일반 기능이 모두 포함되어 있습니다.fmean
,fmedian
,fmode
,fsum
,fprod
,fsd
,fvar
,fmin
,fmax
,ffirst
,flast
,fNobs
,fNdistinct
,fscale
,fbetween
,fwithin
,fHDbetween
,fHDwithin
,flag
,fdiff
그리고.fgrowth
데이터를 통해 그룹화된 계산을 단일 경로로 수행합니다(즉, 분할 및 재결합 없음).
구문:
fFUN(x, g = NULL, [w = NULL,] TRA = NULL, [na.rm = TRUE,] use.g.names = TRUE, drop = TRUE)
예:
v <- iris$Sepal.Length
f <- iris$Species
# Vectors
fmean(v) # mean
fmean(v, f) # grouped mean
fsd(v, f) # grouped standard deviation
fsd(v, f, TRA = "/") # grouped scaling
fscale(v, f) # grouped standardizing (scaling and centering)
fwithin(v, f) # grouped demeaning
w <- abs(rnorm(nrow(iris)))
fmean(v, w = w) # Weighted mean
fmean(v, f, w) # Weighted grouped mean
fsd(v, f, w) # Weighted grouped standard-deviation
fsd(v, f, w, "/") # Weighted grouped scaling
fscale(v, f, w) # Weighted grouped standardizing
fwithin(v, f, w) # Weighted grouped demeaning
# Same using data.frames...
fmean(iris[-5], f) # grouped mean
fscale(iris[-5], f) # grouped standardizing
fwithin(iris[-5], f) # grouped demeaning
# Same with matrices ...
패키지 vignetes에서 벤치마크를 제공합니다.고속 기능을 사용한 프로그래밍은 dplyr 또는 data.table을 사용한 프로그래밍보다 훨씬 빠릅니다. 특히 작은 데이터에서도 그렇지만 큰 데이터에서도 그렇습니다.
0부터, R4.3.부터,tapply
과 데터프둘지다니다합원및을 모두 합니다.tapply
그리고.by
에서는 공식을 사용하여 데이터 프레임 행을 그룹화할 수 있습니다.
> R.version.string
[1] "R version 4.3.0 beta (2023-04-07 r84200)"
> dd <- data.frame(x = 1:10, f = gl(5L, 2L), g = gl(2L, 5L))
x f g
1 1 1 1
2 2 1 1
3 3 2 1
4 4 2 1
5 5 3 1
6 6 3 2
7 7 4 2
8 8 4 2
9 9 5 2
10 10 5 2
> tapply(dd, ~f + g, nrow)
g
f 1 2
1 2 0
2 2 0
3 1 1
4 0 2
5 0 2
> by(dd, ~g, identity)
g: 1
x f g
1 1 1 1
2 2 1 1
3 3 2 1
4 4 2 1
5 5 3 1
------------------------------------------------------------
g: 2
x f g
6 6 3 2
7 7 4 2
8 8 4 2
9 9 5 2
10 10 5 2
위에서 설명하지 않은 일부 패키지의 대안도 있습니다.
그parApply()
에서 합니다.parallels
패키지는 클러스터에서 병렬 계산을 실행하기 위한 함수 제품군을 적용할 수 있는 대안을 제공합니다. 다른 으로는 R 서 계 산 위 다 대 포 다 함 합 니 다 을 음 은 안 른 병 에 렬 한 을 ▁other ▁the 니 다 합 포 atives ▁for 함 ▁r ▁r ▁altern ▁include ▁comput ation ▁parallel ▁in 을foreach
및 패지및doParallel
패키지 - 루프 및 함수의 병렬 실행을 허용합니다. 그future
패키지는 표현식을 병렬 또는 순차적으로 비동기식으로 평가하는 방법인 미래를 사용하기 위한 간단하고 일관된 API를 제공합니다.추가적으로,purrr
및 접근 하며, 패지는반매복대프접제며공하, 을 통해 를 지원합니다.future
꾸러미
여기 몇 가지 예가 있어요.
parApply() 예:
library(parallel)
# Create a matrix
m <- matrix(1:20, nrow = 5)
# Define a function to apply to each column of the matrix
my_fun <- function(x) {
x^2
}
# Apply the function to each column of the matrix in parallel
result <- parApply(cl = makeCluster(2), X = m, MARGIN = 2, FUN = my_fun)
# View the result
result
각 예:
library(foreach)
library(doParallel)
# Register a parallel backend
registerDoParallel(cores = 2)
# Create a list of numbers
my_list <- list(1, 2, 3, 4, 5)
# Define a function to apply to each element of the list
my_fun <- function(x) {
x^2
}
# Apply the function to each element of the list in parallel
result <- foreach(i = my_list) %dopar% my_fun(i)
# View the result
result
미래의 예:
library(future)
# Plan to use a parallel backend
plan(multiprocess)
# Create a list of numbers
my_list <- list(1, 2, 3, 4, 5)
# Define a function to apply to each element of the list
my_fun <- function(x) {
x^2
}
# Apply the function to each element of the list in parallel using futures
result <- future_map(my_list, my_fun)
# View the result
result
purr 예:
library(purrr)
library(future)
# Plan to use a parallel backend
plan(multiprocess)
# Create a list of numbers
my_list <- list(1, 2, 3, 4, 5)
# Define a function to apply to each element of the list
my_fun <- function(x) {
x^2
}
# Apply the function to each element of the list in parallel using purrr
result <- future_map(my_list, my_fun)
# View the result
result
언급URL : https://stackoverflow.com/questions/3505701/grouping-functions-tapply-by-aggregate-and-the-apply-family
'source' 카테고리의 다른 글
Python Pandas에서 데이터 프레임에서 두 값 사이의 행을 선택하는 방법은 무엇입니까? (0) | 2023.07.06 |
---|---|
"이 작업을 수행하려면 IIS 통합 파이프라인 모드가 필요합니다." (0) | 2023.07.06 |
Array .find() 메서드 매개 변수가 vuex에 정의되지 않았습니다. (0) | 2023.07.06 |
MongoDB에 안정적으로 다시 연결 (0) | 2023.07.01 |
main 앞에 함수 호출 (0) | 2023.07.01 |