如何访问vector中的最后一个值?

假设我有一个嵌套在一个或两个数据框中的向量。 是否有一个快速和肮脏的方式来访问最后一个值,而不使用length()函数? ala PERL的$#特别var?

所以我想像这样的东西:

 dat$vec1$vec2[$#] 

代替

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

我使用tail()函数:

 tail(vector, n=1) 

tail()好处在于它也可以处理数据框,与x[length(x)]成语不同。

如果你正在寻找像Python的x [-1]那样好的东西,我想你倒霉了。 标准习语是

 x[length(x)] 

但是编写一个函数来做到这一点很简单:

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

R中的这个缺失的function也让我很烦恼!

结合林德洛夫和格雷格林德的想法:

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

在提示符下工作时,通常省略“ n= ”,即tail(x, 1)

pastecs软件包中的last不同, headtail (来自utils )不仅可以在vector上工作,还可以在数据框等上工作,还可以返回“没有第一个/最后n个元素”的数据,例如

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

(请注意,您必须使用head来代替tail 。)

为了回答这个问题,不是从审美的,但是以绩效为导向的angular度来看,我把所有的上述build议都通过了一个基准 。 确切地说,我已经考虑过这些build议

  • 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)。 在我们查看数字之前,我认为应该清楚的是,任何变得明显较慢的input大小(即任何不是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 

这立即排除了任何涉及revend事情,因为它们显然不是O(1) (并且结果expression式以非懒惰的方式进行评估)。 taildplyr::lastO(1)不远,但也比mylast(x)x[length(x)]慢得多。 由于mylast(x)x[length(x)]慢,并没有提供任何好处(相反,它是自定义的,并且不会优雅地处理空向量),所以我认为答案很清楚: 请使用x[length(x)]

我只用663,552行的dataframe对这两种方法进行了基准testing:

 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 

所以,假设你正在使用vector,访问长度的位置要快得多。

另一种方法是取反向量的第一个元素:

 rev(dat$vect1$vec2)[1] 

dplyr包中包含一个函数last()

 last(mtcars$mpg) # [1] 21.4 

我有另一种方法来查找向量中的最后一个元素。 说vector是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 

你走了!

Package data.table包含last函数

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

怎么样

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

xts包提供了lastfunction:

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