I want to pass a column name to a function and use column indexing and the setorder
function:
require(data.table)
data(iris)
top3 = function(t, n) {
setorder(t, n, order=-1)
return ( t[1:3, .(Species, n)])
}
DT = data.table(iris)
top3(DT, Petal.Width)
However, this returns an error:
Error in setorderv(x, cols, order, na.last) :
some columns are not in the data.table: n,1
I think I'm misunderstanding how passing bare column names works in R. What are my options?
You can do
top3 = function(DT, nm) eval(substitute( DT[order(-nm), .(Species, nm)][, head(.SD, 3L)] ))
top3(DT, Petal.Width)
Species Petal.Width
1: virginica 2.5
2: virginica 2.5
3: virginica 2.5
I would advise against (1) setorder
inside a function, since it has side effects; (2) indexing with 1:3
when you may use this on a data.table with fewer than three rows in the future, to strange effect; (3) fixing 3
instead of making it an argument to the function; and (4) using n
for name... just my personal preference to reserve n
for counts.
Assuming your dataset will always have more than 3 rows and that this is the ONLY operation you want to perform on that data table, it may be in your interest to use setorderv
instead.
top3 = function(t, n) {
setorderv(t, n, -1)
return ( t[1:3, c("Species", n), with=FALSE])
}
DT = data.table(iris)
top3(DT, "Petal.Width")
Result:
Species Petal.Width
1: virginica 2.5
2: virginica 2.5
3: virginica 2.5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With