벡터의 마지막 n 개 요소를 가져옵니다. length () 함수를 사용하는 것보다 더 좋은 방법이 있습니까?
인수를 위해 Python에서 길이가 10 인 벡터의 마지막 5 개 요소를 원하면 범위 인덱스에서 "-"연산자를 사용하여 다음과 같이 할 수 있습니다.
>>> x = range(10)
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x[-5:]
[5, 6, 7, 8, 9]
>>>
R에서이를 수행하는 가장 좋은 방법은 무엇입니까? length () 함수를 사용하는 현재 기술보다 더 깨끗한 방법이 있습니까?
> x <- 0:9
> x
[1] 0 1 2 3 4 5 6 7 8 9
> x[(length(x) - 4):length(x)]
[1] 5 6 7 8 9
>
이 질문은 최근 데이터에 대해서만 작업하는 것이 유용한 시계열 분석 btw와 관련이 있습니다.
참조 ?tail
및 ?head
몇 가지 편리한 기능 :
> x <- 1:10
> tail(x,5)
[1] 6 7 8 9 10
인수를 위해 마지막 5 개 요소를 제외한 모든 것은 다음과 같습니다.
> head(x,n=-5)
[1] 1 2 3 4 5
@Martin Morgan이 의견에서 말했듯이, 1 억 개의 값으로 구성된 벡터에서이 작업을 백만 번 수행해야하는 경우 꼬리 솔루션보다 빠른 다른 두 가지 가능성이 있습니다. 가독성을 위해 꼬리를 사용합니다.
test elapsed relative
tail(x, 5) 38.70 5.724852
x[length(x) - (4:0)] 6.76 1.000000
x[seq.int(to = length(x), length.out = 5)] 7.53 1.113905
벤치마킹 코드 :
require(rbenchmark)
x <- 1:1e8
do.call(
benchmark,
c(list(
expression(tail(x,5)),
expression(x[seq.int(to=length(x), length.out=5)]),
expression(x[length(x)-(4:0)])
), replications=1e6)
)
의 승인 tail
속도에 따라 여기에 혼자 정말 당신이 x의 길이가 초과 할 확실하지 않으면 꼬리와 작업에 안전하다는 사실에서 오는 느린 속도의 그 부분을 강조하지 않는 것 n
, 수 하위 집합을 만들려는 요소 :
x <- 1:10
tail(x, 20)
# [1] 1 2 3 4 5 6 7 8 9 10
x[length(x) - (0:19)]
#Error in x[length(x) - (0:19)] :
# only 0's may be mixed with negative subscripts
Tail은 오류를 생성하는 대신 최대 요소 수를 반환하므로 직접 오류를 검사 할 필요가 없습니다. 그것을 사용하는 큰 이유. 추가 마이크로 초 / 밀리 초가 사용하는 데별로 중요하지 않은 경우 더 안전한 코드입니다.
두 개의 문자를 더 사용하여 R에서도 똑같은 일을 할 수 있습니다.
x <- 0:9
x[-5:-1]
[1] 5 6 7 8 9
또는
x[-(1:5)]
어때요 rev(x)[1:5]
?
x<-1:10
system.time(replicate(10e6,tail(x,5)))
user system elapsed
138.85 0.26 139.28
system.time(replicate(10e6,rev(x)[1:5]))
user system elapsed
61.97 0.25 62.23
여기에 그것을 수행하는 기능이 있으며 합리적으로 빠르게 보입니다.
endv<-function(vec,val)
{
if(val>length(vec))
{
stop("Length of value greater than length of vector")
}else
{
vec[((length(vec)-val)+1):length(vec)]
}
}
용법:
test<-c(0,1,1,0,0,1,1,NA,1,1)
endv(test,5)
endv(LETTERS,5)
기준:
test replications elapsed relative
1 expression(tail(x, 5)) 100000 5.24 6.469
2 expression(x[seq.int(to = length(x), length.out = 5)]) 100000 0.98 1.210
3 expression(x[length(x) - (4:0)]) 100000 0.81 1.000
4 expression(endv(x, 5)) 100000 1.37 1.691
여기에 관련 내용을 추가합니다. 백엔드 인덱스가있는 벡터에 액세스하고 싶었습니다. 즉 , 전체 꼬리가 tail(x, i)
아니라 반환하는 것과 같은 것을 작성하고 싶었습니다 x[length(x) - i + 1]
.
주석에 따라 두 가지 솔루션을 벤치마킹했습니다.
accessRevTail <- function(x, n) {
tail(x,n)[1]
}
accessRevLen <- function(x, n) {
x[length(x) - n + 1]
}
microbenchmark::microbenchmark(accessRevLen(1:100, 87), accessRevTail(1:100, 87))
Unit: microseconds
expr min lq mean median uq max neval
accessRevLen(1:100, 87) 1.860 2.3775 2.84976 2.803 3.2740 6.755 100
accessRevTail(1:100, 87) 22.214 23.5295 28.54027 25.112 28.4705 110.833 100
따라서이 경우에는 작은 벡터의 경우에도 tail
직접 액세스에 비해 매우 느립니다.
'Programing' 카테고리의 다른 글
shared_ptr을 언제 사용하고 언제 원시 포인터를 사용합니까? (0) | 2020.10.30 |
---|---|
왜 이것을 확인하십시오! = null? (0) | 2020.10.30 |
C #에서 FFT (고속 푸리에 변환) 구현 (0) | 2020.10.30 |
ANSI 이스케이프 (터미널 형식 / 색상 코드)를 HTML로 변환하는 라이브러리 (0) | 2020.10.30 |
명령 줄 또는 배치 파일에서 Excel 매크로를 실행하는 방법은 무엇입니까? (0) | 2020.10.30 |