Because of this...
if (!length(x))
return(x)
...in the code of first, the result of first(x) is not the same as x[1] when x is a zero-length vector: x vs. NA. Which is perfectly fine, but you may consider clarifying this difference in the help text.
A small example to illustrate the setting where this difference bit me. Find the first index of x == 1, within each group, where group "b" have no 1s
d <- data.table(grp = c("a", "a", "a", "b", "b", "c", "c"),
x = c(0, 1, 1, 0, 0, 1, 1))
# grp x
# 1: a 0
# 2: a 1
# 3: a 1
# 4: b 0
# 5: b 0
# 6: c 1
# 7: c 1
# select first element using [1]
d[ , .(first.true = which(x == 1)[1]), by = grp]
# grp first.true
# 1: a 2
# 2: b NA <~~ zero-length result of grp b appears as NA
# 3: c 1
# select first element using `first`
d[ , .(first.true = first(which(x == 1))), by = grp]
# grp first.true
# 1: a 2 <~~ zero-length result of grp b is "gone"
# 2: c 1
Because of this...
...in the code of
first, the result offirst(x)is not the same asx[1]whenxis a zero-length vector:xvs.NA. Which is perfectly fine, but you may consider clarifying this difference in the help text.A small example to illustrate the setting where this difference bit me. Find the first index of
x == 1, within each group, where group "b" have no1s