3

I had the vector x<-1:5 I named its elements (wrongly) names(x)<-rep(c(letters[1:4], "a")). How can I access the last element by name? x["a"] only return the first element named "a".

MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
Fabian Gil
  • 89
  • 1
  • 4
  • related: https://stackoverflow.com/questions/77434/how-to-access-the-last-value-in-a-vector?rq=1 – talat Feb 25 '16 at 22:12

2 Answers2

9

How about:

x[names(x) == "a"]
# a a 
# 1 5 

Or to get only the final one:

x[tail(which(names(x) == "a"), 1L)]
# a 
# 5

This is more readable but marginally slower than getting at what tail does directly (see getAnywhere("tail.default")):

x[(idx <- which(names(x) == "a"))[length(idx)]
# a 
# 5
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • You could add an info about `tail` to get the last element which I find easier. (And on a side note, it would also work without the `which`) – talat Feb 25 '16 at 22:11
  • 1
    I would actually use `tail(x[names(x) == "a"], 1)` but it's personal preference of course – talat Feb 25 '16 at 22:18
1

The function duplicated() will give a boolean vector of occurrences except the first. In your case it would be only the second "a". Consequently,

x[duplicated(names(x))]

would give you the second entry. If you add more "a"-entries to the dataframe, you would get a vector of 2,3 and so on elements. All except the first. In that case you would have to cycle through or something.

niid
  • 473
  • 4
  • 13
  • I think this approach is misleading for the problem at hand. I happens to work for this minimal example but could be completely wrong for "real world" data. – talat Feb 25 '16 at 22:16
  • Why is it less robust than the other solution? I can also throw a head() or tail() at this. – niid Feb 25 '16 at 22:19
  • It's not "robust" a) because you don't reference the name `a` which is asked for - this means that if any other name, e.g. `b` was also duplicated, those would also be returned, and b) they want to access only the last element while your approach would return all except the first occurence - which only happens to work because there are exactly two occurences of `a` in `x`. Consider: `x <- 1:10; names(x) <- sample(letters[1:3], 10, TRUE)` – talat Feb 25 '16 at 22:27
  • a) is true I overlooked that – niid Feb 25 '16 at 22:29
  • Also note that it would need to be written as `x[duplicated(names(x))]`, i.e. `()`instead of `[]` – talat Feb 25 '16 at 22:31