벡터의 마지막 값에 액세스하는 방법은 무엇입니까?
한 개 또는 두 개의 수준을 가진 데이터 프레임에 내포된 벡터가 있다고 가정합니다.사용하지 않고 마지막 값에 액세스할 수 있는 빠르고 더러운 방법이 있습니까?length()
기능?PERL의 어떤 것.$#
특별한 var?
그래서 저는 다음과 같은 것을 원합니다.
dat$vec1$vec2[$#]
다음 대신:
dat$vec1$vec2[length(dat$vec1$vec2)]
나는 사용합니다.tail
함수:
tail(vector, n=1)
좋은 점은tail
데이터 프레임에서도 작동한다는 것입니다.x[length(x)]
관용구
미학적인 관점이 아니라 성능 지향적인 관점에서 이에 답하기 위해 위의 모든 제안을 벤치마크에 넣었습니다.정확히 말하자면, 저는 그 제안들을 고려했습니다.
x[length(x)]
mylast(x)
,어디에mylast
는 Rcpp를 통해 구현된 C++ 함수입니다.tail(x, n=1)
dplyr::last(x)
x[end(x)[1]]]
rev(x)[1]
다양한 크기(10^3, 10^4, 10^5, 10^6, 10^7)의 무작위 벡터에 적용했습니다.숫자를 보기 전에 입력 크기가 클수록 눈에 띄게 느려지는 것(즉, O(1)이 아닌 것)은 옵션이 아니라는 점을 분명히 해야 한다고 생각합니다.제가 사용한 코드는 다음과 같습니다.
Rcpp::cppFunction('double mylast(NumericVector x) { int n = x.size(); return x[n-1]; }')
options(width=100)
for (n in c(1e3,1e4,1e5,1e6,1e7)) {
x <- runif(n);
print(microbenchmark::microbenchmark(x[length(x)],
mylast(x),
tail(x, n=1),
dplyr::last(x),
x[end(x)[1]],
rev(x)[1]))}
그것은 나를 줍니다.
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 171 291.5 388.91 337.5 390.0 3233 100
mylast(x) 1291 1832.0 2329.11 2063.0 2276.0 19053 100
tail(x, n = 1) 7718 9589.5 11236.27 10683.0 12149.0 32711 100
dplyr::last(x) 16341 19049.5 22080.23 21673.0 23485.5 70047 100
x[end(x)[1]] 7688 10434.0 13288.05 11889.5 13166.5 78536 100
rev(x)[1] 7829 8951.5 10995.59 9883.0 10890.0 45763 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 204 323.0 475.76 386.5 459.5 6029 100
mylast(x) 1469 2102.5 2708.50 2462.0 2995.0 9723 100
tail(x, n = 1) 7671 9504.5 12470.82 10986.5 12748.0 62320 100
dplyr::last(x) 15703 19933.5 26352.66 22469.5 25356.5 126314 100
x[end(x)[1]] 13766 18800.5 27137.17 21677.5 26207.5 95982 100
rev(x)[1] 52785 58624.0 78640.93 60213.0 72778.0 851113 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 214 346.0 583.40 529.5 720.0 1512 100
mylast(x) 1393 2126.0 4872.60 4905.5 7338.0 9806 100
tail(x, n = 1) 8343 10384.0 19558.05 18121.0 25417.0 69608 100
dplyr::last(x) 16065 22960.0 36671.13 37212.0 48071.5 75946 100
x[end(x)[1]] 360176 404965.5 432528.84 424798.0 450996.0 710501 100
rev(x)[1] 1060547 1140149.0 1189297.38 1180997.5 1225849.0 1383479 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 327 584.0 1150.75 996.5 1652.5 3974 100
mylast(x) 2060 3128.5 7541.51 8899.0 9958.0 16175 100
tail(x, n = 1) 10484 16936.0 30250.11 34030.0 39355.0 52689 100
dplyr::last(x) 19133 47444.5 55280.09 61205.5 66312.5 105851 100
x[end(x)[1]] 1110956 2298408.0 3670360.45 2334753.0 4475915.0 19235341 100
rev(x)[1] 6536063 7969103.0 11004418.46 9973664.5 12340089.5 28447454 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 327 722.0 1644.16 1133.5 2055.5 13724 100
mylast(x) 1962 3727.5 9578.21 9951.5 12887.5 41773 100
tail(x, n = 1) 9829 21038.0 36623.67 43710.0 48883.0 66289 100
dplyr::last(x) 21832 35269.0 60523.40 63726.0 75539.5 200064 100
x[end(x)[1]] 21008128 23004594.5 37356132.43 30006737.0 47839917.0 105430564 100
rev(x)[1] 74317382 92985054.0 108618154.55 102328667.5 112443834.0 187925942 100
이것은 즉시 관련된 모든 것을 배제합니다.rev
또는end
그들은 분명히 그렇지 않기 때문에.O(1)
(그리고 결과적인 표현식은 비반복적인 방식으로 평가됩니다.) tail
그리고.dplyr::last
머지않아O(1)
하지만 그들은 또한 상당히 느립니다.mylast(x)
그리고.x[length(x)]
.부터mylast(x)
보다 느림x[length(x)]
그리고 이점을 제공하지 않습니다(오히려, 그것은 사용자 정의이고 빈 벡터를 우아하게 처리하지 않습니다). 저는 답이 명확하다고 생각합니다: 사용하십시오.
파이썬의 x[-1] 표기법과 같은 멋진 것을 찾고 있다면, 운이 다했다고 생각합니다.표준 관용구는 다음과 같습니다.
x[length(x)]
그러나 이를 위한 함수를 작성하는 것은 충분히 쉽습니다.
last <- function(x) { return( x[length(x)] ) }
Ran의 이 누락된 기능도 나를 짜증나게 합니다!
last <- function(x) { tail(x, n = 1) }
프롬프트에서 작업할 때, 나는 보통 생략합니다.n=
,예.tail(x, 1)
.
와는 달리last
에서pastecs
패키지,head
그리고.tail
(부터)utils
)는 벡터뿐만 아니라 데이터 프레임 등에서도 작동하며, "첫 번째/마지막 n개 요소 없이" 데이터를 반환할 수 있습니다.
but.last <- function(x) { head(x, n = -1) }
(사용자가 사용해야 합니다.head
이를 위해, 대신에tail
.)
dplyr 패키지에는 기능이 포함되어 있습니다.last()
:
last(mtcars$mpg)
# [1] 21.4
저는 다음 코드를 사용하여 663,552 행의 데이터 프레임에 대한 이 두 가지 접근 방식을 벤치마킹했습니다.
system.time(
resultsByLevel$subject <- sapply(resultsByLevel$variable, function(x) {
s <- strsplit(x, ".", fixed=TRUE)[[1]]
s[length(s)]
})
)
user system elapsed
3.722 0.000 3.594
그리고.
system.time(
resultsByLevel$subject <- sapply(resultsByLevel$variable, function(x) {
s <- strsplit(x, ".", fixed=TRUE)[[1]]
tail(s, n=1)
})
)
user system elapsed
28.174 0.000 27.662
따라서 벡터로 작업한다고 가정하면 길이 위치에 액세스하는 것이 훨씬 더 빠릅니다.
또 다른 방법은 역 벡터의 첫 번째 요소를 취하는 것입니다.
rev(dat$vect1$vec2)[1]
벡터에서 마지막 요소를 찾는 다른 방법이 있습니다.벡터가 다음과 같다고 가정합니다.a
.
> a<-c(1:100,555)
> end(a) #Gives indices of last and first positions
[1] 101 1
> a[end(a)[1]] #Gives last element in a vector
[1] 555
잘했어!
패지data.table
를 포함합니다.last
를 수행
library(data.table)
last(c(1:10))
# [1] 10
에 대해서는?
> a <- c(1:100,555)
> a[NROW(a)]
[1] 555
는 xts를 제공합니다.last
함수:
library(xts)
a <- 1:100
last(a)
[1] 100
1.0.0을 기준으로 에서는 오른쪽에서 색인화할 음수 정수를 사용합니다.
library(purrr)
pluck(LETTERS, -1)
"Z"
언급URL : https://stackoverflow.com/questions/77434/how-to-access-the-last-value-in-a-vector
'sourcetip' 카테고리의 다른 글
R에서 %>% 함수는 무엇을 의미합니까? (0) | 2023.06.17 |
---|---|
루비 코드를 어떻게 문서화합니까? (0) | 2023.06.17 |
Vue 3 및 Vite 프로젝트에 유형 스크립트를 추가하는 방법 (0) | 2023.06.17 |
C에서 폐쇄를 달성할 수 있는 방법이 있습니까? (0) | 2023.06.12 |
Firebase 서비스 작업자와 Vue/Vuex 웹 애플리케이션 간의 통신 방법 (0) | 2023.06.12 |