Подтвердить что ты не робот

Использование .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, а не КАК их использовать.

4b9b3361

Ответ 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.