sourcetip

벡터의 마지막 값에 액세스하는 방법은 무엇입니까?

fileupload 2023. 6. 17. 09:36
반응형

벡터의 마지막 값에 액세스하는 방법은 무엇입니까?

한 개 또는 두 개의 수준을 가진 데이터 프레임에 내포된 벡터가 있다고 가정합니다.사용하지 않고 마지막 값에 액세스할 수 있는 빠르고 더러운 방법이 있습니까?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

반응형