it-swarm-tr.com

Bir vektördeki son değere nasıl erişilir?

Bir veya iki düzeyde bir veri çerçevesine yerleştirilmiş bir vektörüm olduğunu varsayalım. length() işlevini kullanmadan, son değere erişmenin hızlı ve kirli bir yolu var mı? Bir şey ala Perl _ $# özel var?

Bu yüzden şöyle bir şey istiyorum:

dat$vec1$vec2[$#]

onun yerine

dat$vec1$vec2[length(dat$vec1$vec2)]
256
user14008

tail işlevini kullanıyorum:

tail(vector, n=1)

tail olan güzel şey, x[length(x)] deyiminin aksine, veri çerçeveleri üzerinde de çalışmasıdır.

330
lindelof

Bunu estetik değil, performans odaklı bir bakış açısıyla cevaplamak için yukarıdaki tüm önerileri bir kıyaslama yoluyla verdim. Kesin olarak, önerileri düşündüm

  • x[length(x)]
  • mylast(x), burada mylast, Rcpp aracılığıyla uygulanan bir C++ işlevidir,
  • tail(x, n=1)
  • dplyr::last(x)
  • x[end(x)[1]]]
  • rev(x)[1]

ve bunları, çeşitli büyüklükteki rastgele vektörlere (10 ^ 3, 10 ^ 4, 10 ^ 5, 10 ^ 6 ve 10 ^ 7) uyguladı. Rakamlara bakmadan önce, daha büyük giriş boyutuyla gözle görülür şekilde yavaşlayan herhangi bir şeyin (yani, O(1)) olmayan bir şeyin bir seçenek olmadığı açıkça anlaşılmalıdır. İşte kullandığım kod:

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]))}

Bana verir

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

Bu, rev veya end ile ilgili her şeyi hemen dışlar, çünkü açıkça O(1) değildir (ve elde edilen ifadeler tembel olmayan bir şekilde değerlendirilir). tail ve dplyr::lastO(1) olmaktan çok uzak değil, ancak mylast(x) ve x[length(x)] öğelerine göre oldukça yavaşlar. mylast(x)x[length(x)] değerinden daha yavaş olduğundan ve hiçbir fayda sağlamadığından (aksine, özeldir ve boş bir vektörü dikkatlice işlemez), cevabın açık olduğunu düşünüyorum: Lütfen x[length(x)] kullanın.

143
anonymous

Python'un x [-1] notasyonu kadar güzel bir şey arıyorsanız, şanssız olduğunuzu düşünüyorum. Standart deyim

x[length(x)]  

ancak bunu yapmak için bir fonksiyon yazmak yeterince kolaydır:

last <- function(x) { return( x[length(x)] ) }

R'deki bu eksik özellik beni de rahatsız ediyor!

104
Gregg Lind

lindelof's ve Gregg Lind's fikirlerini birleştiriyor:

last <- function(x) { tail(x, n = 1) }

İstemde çalışırken, genellikle n=, yani tail(x, 1) atlar.

last, pastecs paketinden farklı olarak, head ve tail (utils) 'dan yalnızca vektörlerde değil, veri çerçevelerinde de çalışır. "ilk/son n öğesi olmadan" verilerini döndür, örneğin.

but.last <- function(x) { head(x, n = -1) }

(Bunun için head yerine tail kullanmanız gerektiğini unutmayın. ”

44
Florian Jenn

Bu iki yaklaşımı veri çerçevesi üzerinde 663,552 sıra ile aşağıdaki kodu kullanarak kıyasladım:

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 

ve

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 

Dolayısıyla, vektörlerle çalıştığınızı varsayalım, uzunluk konumuna erişmek önemli ölçüde daha hızlıdır.

17
scuerda

dplyr paketi bir işlev içerir last():

last(mtcars$mpg)
# [1] 21.4
16
Sam Firke

Başka bir yol, ters çevrilmiş vektörün ilk elemanını almaktır:

rev(dat$vect1$vec2)[1]
12
James

Bir vektördeki son elemanı bulmak için başka bir yöntemim var. Diyelim ki vektör 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

İşte burda!

9
Akash

Paket data.tablelast işlevini içerir

library(data.table)
last(c(1:10))
# [1] 10

Ne hakkında

> a <- c(1:100,555)
> a[NROW(a)]
[1] 555
7
Kurt Ludikovsky

Xts paketi last işlevi sağlar:

library(xts)
a <- 1:100
last(a)
[1] 100
2
smoff