关于r:如何访问向量中的最后一个值?

关于r:如何访问向量中的最后一个值?

How to access the last value in a vector?

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

所以我想要这样的东西:

1
dat$vec1$vec2[$#]

代替

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

我使用tail函数:

1
tail(vector, n=1)

x[length(x)]习惯用法不同,tail的好处是它也适用于数据帧。


为了不是从美学角度而是以性能为导向来回答这个问题,我已将上述所有建议通过基准进行了分析。确切地说,我已经考虑了建议

  • 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)的事物)都不是选择。这是我使用的代码:

1
2
3
4
5
6
7
8
9
10
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]))}

它给我

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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)(并且结果表达式以非惰性方式求值)。 taildplyr::lastO(1)并不远,但它们也比mylast(x)x[length(x)]慢得多。由于mylast(x)x[length(x)]慢并且没有任何好处(相反,它是自定义的,不会优雅地处理空向量),我认为答案很明确:请使用x[length(x)]


如果您正在寻找与Python的x [-1]表示法一样好的东西,我认为您很不走运。标准成语是

1
x[length(x)]

但是编写一个函数来做到这一点很容易:

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

R中缺少的这个功能也让我很烦!


结合lindelof和Gregg Lind的想法:

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

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

pastecs包中的last不同,headtail(来自utils)不仅适用于矢量,还适用于数据帧等,并且还可以"不带前/后n个元素"返回数据。 ,例如

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

(请注意,您必须为此使用head,而不是tail。)


dplyr软件包包括一个函数last()

1
2
last(mtcars$mpg)
# [1] 21.4

我刚刚使用以下代码在663552行的数据帧上对这两种方法进行了基准测试:

1
2
3
4
5
6
7
8
9
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

1
2
3
4
5
6
7
8
9
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

因此,假设您正在使用向量,则访问长度位置的速度明显更快。


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

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

软件包data.table包含last功能

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

我有另一种方法来查找向量中的最后一个元素。
假设向量为a

1
2
3
4
5
> 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

你去!


关于什么

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

xts包提供了last函数:

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


推荐阅读

    数据库导出linux命令?

    数据库导出linux命令?,密码,数据,数据库,情况,地址,系统,工具,网上,名字,命

    linux命令与数据流?

    linux命令与数据流?,工作,地址,系统,信息,命令,目录,标准,网络,管理,常用命

    linux恢复数据库命令?

    linux恢复数据库命令?,工具,系统,软件,数据,盘中,密码,命令,备份,数据库,文

    linux储存命令数据?

    linux储存命令数据?,系统,工作,地址,信息,标准,命令,工具,实时,数据,分析,lin

    linux储存命令数据?

    linux储存命令数据?,系统,工作,地址,信息,标准,命令,工具,实时,数据,分析,lin

    linux命令大全数据库?

    linux命令大全数据库?,服务,系统,平台,状态,软件,通用,环境,数据,神州,地址,

    linux上数据库的命令?

    linux上数据库的命令?,服务,系统,信息,地址,命令,密码,工具,管理,数据,单位,

    linux命令dm数据库?

    linux命令dm数据库?,地址,软件,时间,设备,名字,服务,位置,名称,公司,命令,lin

    linux使用命令的方法?

    linux使用命令的方法?,系统,信息,工具,标准,数据,命令,左下角,目录,文件夹,

    linux存储数据命令?

    linux存储数据命令?,系统,管理,数据,设备,情况,地址,工作,命令,服务,平台,Lin

    linux数据库查找命令?

    linux数据库查找命令?,位置,名称,状态,服务,软件,信息,系统,命令,名字,密码,

    linux数据库同步命令?

    linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

    linux建立数据库命令?

    linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

    linux命令进数据库?

    linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

    linux清空表数据命令?

    linux清空表数据命令?,系统,数据,软件,名称,不了,命令,文件,电脑,地址,位置,L

    linux拷贝数据命令?

    linux拷贝数据命令?,系统,地址,文件,数据,命令,目录,服务,基本知识,项目,密

    linux数据库检查命令?

    linux数据库检查命令?,服务,状态,地址,位置,系统,信息,命令,工作,情况,密码,

    linux命令进去数据库?

    linux命令进去数据库?,地址,服务,名字,系统,数据库,工具,基础,工作,管理,网

    linux数据库基础命令?

    linux数据库基础命令?,地址,工作,基础,系统,命令,信息,情况,工具,设备,目录,l

    linux数据共享命令?

    linux数据共享命令?,情况,系统,工具,网络,数据,软件,发行,设备,命令,文件,Lin