Dirk
Dirk

Reputation: 1324

Select row from data.table in programming mode

You find the main part of my starting solution in this answer. Now I would like to use it in program code and want to replace the column names by variables. Here is my MWE which throws errors in the last lines:

library(data.table)
set.seed(1)
tb = data.table(g_id = c(1, 1, 1, 2, 2, 2, 3),
                item_no = sample(c(24,25,26,27,28,29,30)),
                time_no = c(100, 110, 120, 130, 140, 160, 170)
                )

# get row with minimum value
# works
tb[, .SD[which.min(item_no)], by = g_id]
# now step by step with variables
mincol = "item_no"
grp = "g_id"
# works
tb[, .SD[which.min(item_no)], by = c(grp)]
# doesn't work
tb[, .SD[which.min(..mincol)], by = c(grp)]

Do you have any ideas to run this code with variables?

Thanks!

Upvotes: 1

Views: 111

Answers (2)

Cole
Cole

Reputation: 11255

Here are a couple of alternatives as well. The first method subsets the .SD using the extract operator which.min(.SD[[mincol]]):

#way 1
tb[tb[, .I[which.min(.SD[[mincol]])], by = grp]$V1] #or
tb[, .SD[which.min(.SD[[mincol]])], by = grp]

The second way uses setorderv() to update-in-place the dataset and then uses unique to further subset. Obviously, the reordering may not be a desirable side effect.

#way 2 that can produce a different order
setorderv(tb, mincol)
unique(tb, by = grp)

Upvotes: 1

Vidhya G
Vidhya G

Reputation: 2330

One possibility is to use get:

tb[, .SD[which.min(get(mincol))], by = c(grp)]

Upvotes: 3

Related Questions