Использование .I для возврата номеров строк с помощью пакета data.table
Кто-нибудь, пожалуйста, объясните мне правильное использование .I
для возврата номеров строк в data.table?
У меня есть такие данные:
require(data.table)
DT <- data.table(X=c(5, 15, 20, 25, 30))
DT
# X
# 1: 5
# 2: 15
# 3: 20
# 4: 25
# 5: 30
Я хочу вернуть вектор индексов строк, где условие в i
равно TRUE
, например. какие строки имеют X
больше 20.
DT[X > 20]
# rows 4 & 5 are greater than 20
Чтобы получить индексы, я попытался:
DT[X > 20, .I]
# [1] 1 2
... но ясно, что я делаю это неправильно, потому что это просто возвращает вектор, содержащий 1, в число возвращаемых строк. (Который я думал, был в значительной степени тем, для чего был .N
).
Извините, если это кажется очень простым, но все, что мне удалось найти в документации data.table, это WHAT .I
и .N
do, а не КАК их использовать.
Ответы
Ответ 1
Если все, что вам нужно, это номера строк, а не сами строки, используйте which = TRUE
, а не .I
.
DT[X > 20, which = TRUE]
# [1] 4 5
Таким образом вы получаете преимущества оптимизации i
, например быстрые соединения или использование автоматического индекса. which = TRUE
заставляет его возвращаться раньше, только с номерами строк.
Здесь находится ручная запись для аргумента which
внутри data.table:
TRUE
возвращает номера строк x
, к которым соответствует i
. Если NA
, возвращается номера строк i
, которые не совпадают в x
. По умолчанию FALSE
и строки в x
, которые соответствуют.
Объяснение:
Обратите внимание, что существует определенная связь между .I
и аргументом i = ..
в DT[i = .., j = .., by = ..]
А именно, .I
- это вектор номеров строк в поднаборной таблице.
### Lets create some sample data
set.seed(1)
LL <- sample(LETTERS[1:5], 20, TRUE)
DT <- data.table(X=LL)
посмотрите на разницу между подмножеством всей таблицы и подмножеством только .I
DT[X == "B", .I]
# [1] 1 2 3 4 5 6
DT[ , .I[X == "B"] ]
# [1] 1 2 5 11 14 19
Ответ 2
Извините, если это кажется очень простым, но все, что я смог найти в документации data.table, это WHAT.I и .N делать, а не КАК их использовать.
Сначала проверьте документацию. Я набрал ?data.table
и искал .I
. Вот что там:
Дополнительно: При группировке могут использоваться символы .SD,.BY,.N,.I и .GRP в выражении j, определяемом следующим образом.
.I - целочисленный вектор, равный seq_len (nrow (x)). При группировке, это удерживает для каждого элемента в группе местоположение строки в x. Это полезно для подмножества в j; например DT [,.I [who.max(somecol)], by = grp].
Акцент, добавленный мной здесь. Первоначальное намерение состояло в том, чтобы .I
использоваться во время группировки. Обратите внимание, что на самом деле есть пример в документации по использованию HOW .I
.
Вы не группируете.
Тем не менее, то, что вы пробовали, было разумным. Со временем эти символы стали использоваться, когда они не группируются. Может быть, случай, когда .I
должен вернуть то, что вы ожидали. Я вижу, что использование .I
в j
вместе с i
и by
может быть полезно. В настоящее время .I
не представляется полезным, когда присутствует i
, как вы указали.
Использование функции which()
является хорошим, но может обойти оптимизацию в i
(which()
нужен длинный логический ввод, который должен быть создан и передан ему). Использование аргумента which=TRUE
является хорошим, но затем просто возвращает номера строк (вы не могли тогда что-то делать с этими номерами строк в j
по группе).
Запрос функции # 1494, чтобы обсудить изменение .I
, чтобы работать так, как вы ожидали. Документация содержит слова "местоположение строки в x", что подразумевало бы то, что вы ожидали, поскольку x
- это вся таблица данных.
Ответ 3
В качестве альтернативы,
DataTable[ , which(X>10) ]
вероятно, легче понять и более идиоматически R.