Извлечь столбцы из таблицы данных по числовым индексам, хранящимся в векторе

Я хочу извлечь 4-й, 5-й и 6-й столбцы из таблицы данных с именем dt

работает следующий метод:

    dt[, c(4,5,6)]

но следующее нет:

    a = c(4,5,6)
    dt[, a]

Фактически, второй метод дает мне результат:

    4 5 6

Может кто-нибудь сказать мне, почему это происходит? Два метода выглядят эквивалентными для меня.


person Amazonian    schedule 12.03.2018    source источник
comment
прочитайте data.table часто задаваемые вопросы: cran.r- project.org/web/packages/data.table/vignettes/   -  person MichaelChirico    schedule 12.03.2018
comment
В этом вопросе также обсуждаются несколько решений, которые будут работать: stackoverflow.com/questions/13383840/   -  person thelatemail    schedule 12.03.2018


Ответы (2)


Мы можем использовать двойные точки (..) перед объектом «a», чтобы извлечь столбцы.

dt[, ..a]
#   col4 col5 col6
#1:    4    5    6
#2:    5    6    7
#3:    6    7    8
#4:    7    8    9

Или другой вариант with = FALSE

dt[, a, with = FALSE]

данные

dt <- data.table(col1 = 1:4, col2 = 2:5, col3 = 3:6, col4 = 4:7, col5 = 5:8, col6 = 6:9)
person akrun    schedule 12.03.2018
comment
Благодарность! второй способ работает, а первый нет. Я получаю следующую ошибку при использовании ..a: Ошибка в eval(expr, envir, enclos): объект '..a' не найден. Можете ли вы также объяснить, что не так с моим старым кодом? - person Amazonian; 12.03.2018
comment
@Amazonian Не могли бы вы сказать мне packageVersion data.table .. Что касается вашего кода, если вы проверите ?data.table, By default with=TRUE and j is evaluated within the frame of x; column names can be used as variables. When with=FALSE j is a character vector of column names, a numeric/logical vector of column positions to select or of the form startcol:endcol, and the value returned is always a data.table. with=FALSE is often useful in data.table to select columns dynamically. Note that x[, cols, with=FALSE] is equivalent to x[, .SD, .SDcols=cols]. - person akrun; 12.03.2018
comment
@Amazonian Моя версия data.table data.table_1.10.5 - person akrun; 12.03.2018
comment
у меня версия 1.10.0. Я предполагаю, что мой вопрос в том, почему, когда я присваиваю индексы переменной a = c (4,5,6) и использую переменную, она не работает, но когда я просто помещаю индексы как вектор c (4,5 ,6) все работает? - person Amazonian; 12.03.2018
comment
@Amazonian Пожалуйста, обновите свою версию до последней. Объяснение этому дано в предыдущем комментарии. - person akrun; 12.03.2018
comment
Это правильный способ сделать это в data.table. Проголосовал! - person De Novo; 12.03.2018

Ответ @akrun дает вам правильную альтернативу. Если вы хотите знать, зачем вам это нужно, вот более подробное объяснение:

То, как работает операция подмножества data.table, в большинстве случаев выражение j в dt[i, j, by] без i или by оценивается во фрейме таблицы данных и возвращается как есть, независимо от того, имеет ли оно какое-либо отношение к данным. таблицу за скобками. В версиях до 1.9.8 ваш первый фрагмент кода: dt[,c(4, 5, 6)] возвращает числовой вектор c(4, 5, 6), а не 4-й, 5-й и 6-й столбцы. Это изменилось в data.table v1.9.8 (выпущено в ноябре 2016 г.) (прокрутите вниз до v.1.9.8, потенциально критические изменения), потому что люди, что неудивительно, ожидали, что dt[,c(4, 5, 6)] даст 4-й, 5-й и 6-й столбцы. Теперь, если выражение j является именами переменных или числами, with автоматически устанавливается на FALSE. Это фактически создает поведение, похожее на подмножество фрейма данных (не совсем такое же, но похожее).

Таким образом, ваш второй фрагмент кода (где dt[, a] оценивается как a, а не использует a для подмножества столбцов) фактически используется по умолчанию, а первый — это особый случай.

Чтобы проиллюстрировать странное, но стандартное поведение здесь, попробуйте:

dt[, diag(5)]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    0    0    0    0
# [2,]    0    1    0    0    0
# [3,]    0    0    1    0    0
# [4,]    0    0    0    1    0
# [5,]    0    0    0    0    1

Независимо от того, что у вас dt, если это таблица данных, она будет оцениваться как матрица идентичности 5 * 5.

person De Novo    schedule 12.03.2018