2013-06-18 1 views
4

저는 벡터가 v이고 간격 벡터가 w입니다. 각각의 간격에서 함수의 최대 값, f(x)을 찾고 싶습니다. 결과를 찾는 코드를 따르는 것보다 빠른 방법이 있습니까? 예를 들면 :가장 빠른 방법은 각 간격에서 함수의 최대 값을 찾는 것입니다.

v = c(3.5, 2.5, 4, 6.5, 10, 2.3, 1.8, 4.7, 12, 11.5) 
w = c(0, 5, 15, 20) 
f = function(x){x^2} 
> max = unlist(list(sapply(split(v, cut(v, w),drop = TRUE), 
       function(v) v[which.max(f(v))])), use.names = FALSE) 
> max 
[1] 4.7 12.0 
+0

당신는없고 (도움말 파일을 읽기), 아직 출력은 길이가 2 인 벡터입니까? 오히려, 길이 '3'목록을 산출물로 생각하십니까? – flodel

+0

아니요, 숫자가있는 간격없이 결과 만 필요합니다(). – rose

+0

나를 위해 최적화 된 것 같지만'unlist (list ('sapply'를'vapply'로 대체 할 수 있습니다. 한가지주의 할 점은'f'가 당신이 가진 모든 간격마다 한 번 호출된다는 것입니다.) 이것은 병목 일 수 있습니다. 간격이 더 많이 (그리고 더 작아 질 때)'f'가 코딩되는 방법에 따라 달라집니다. –

답변

4

무엇 findIntervaltapply에 대해. findIntervalcut 비슷하지만 최대 값

tapply(f(v),findInterval(v,w),max) 
# 1  2 
# 22.09 144.00 

을 원하는 아니면 사실을 사용할 수 있다면 요인

tapply(v,findInterval(v,w),function(x)x[which.max(f(x))]) 
# 1 2 
# 4.7 12.0 

또는 다음으로 변환하는 오버 헤드없이 기능은 단조 모든 양의 값을 증가하고 있음 하고. 당신이 경계에서 발생하는 지정해야합니다

f(tapply(v,findInterval(v,w),max)) 

참고 w`는 3 개 세트 (하나가 비어)를 정의`것을

library(microbenchmark) 
    microbenchmark(
     mnel = tapply(v,findInterval(v,w),max), 
     flodel = unname(vapply(split(f(v), cut(v, w), drop = TRUE), max, numeric(1L))), 
     flodel2 = unname(vapply(split(seq_along(v), findInterval(v, w)), function(i, v, fv)v[i][which.max(fv[i])], numeric(1L), v, f(v)))) 
# Unit: microseconds 
# expr  min  lq median  uq  max neval 
# mnel 260.945 262.9155 264.2265 276.0645 458.670 100 
# flodel 331.218 334.3585 336.0580 351.1985 694.715 100 
#flodel2 124.998 127.3230 128.5170 137.0505 354.545 100 
+0

결과 헤더 형식을 제거하려면 어떻게합니까? – rose

+0

@rose -'unname' – mnel

+2

@flodel - 추가주의 사항 – mnel

관련 문제