динамические имена столбцов работают, когда: = используется, но не когда = используется в data.table - PullRequest
1 голос
/ 20 июня 2019

Использование этого фиктивного набора данных

setDT(mtcars_copy<-copy(mtcars))
new_col<- "sum_carb" # for dynamic column referencing

Почему Случай 1 работает, а не Случай 2?

# Case 1 - Works fine
mtcars_copy[,eval(new_col):=sum(carb)] # Works fine


# Case 2:Doesnt work
aggregate_mtcars<-mtcars_copy[,(eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,c(eval(new_col)=sum(carb))] # Error

Как заставить Case 2 работать, когда я не хочу, чтобы основная таблица (mtcars_copy в этом случае содержала новые столбцы), но чтобы результаты сохранялись в отдельной таблице агрегации (aggregate_mtcars)

Ответы [ 3 ]

2 голосов
/ 20 июня 2019

Один из вариантов - использовать базовую функцию R setNames

aggregate_mtcars <- mtcars_copy[, setNames(.(sum(carb)), new_col)]

Или вы можете использовать data.table::setnames

aggregate_mtcars <- setnames(mtcars_copy[, .(sum(carb))], new_col)
2 голосов
/ 20 июня 2019

Я думаю, что вы хотите просто сделать копию при выполнении дела 1.

aggregate_mtcars <- copy(mtcars_copy)[, eval(new_col) := sum(carb)]

Сохраняет mtcars_copy как отдельный набор данных для нового aggregate_metcars без новых столбцов.

1 голос
/ 20 июня 2019

Причина в том, что в случае 2 используется data.frame способ создания столбца во фрейме данных (в виде нового списка).В data.table есть скрытый параметр: with, который обрабатывает способ возврата объекта.Это может быть data.table или vector.

? Data.table:
По умолчанию с = TRUE и j оценивается в кадре x;имена столбцов могут быть использованы в качестве переменных.В случае перекрывающихся имен переменных в наборе данных и в родительской области вы можете использовать префикс двойной точки ..cols для явной ссылки на родительскую область переменной 'cols, а не из вашего набора данных.

Когда j является символьным вектором столбцаимена, числовой вектор позиций столбцов для выбора или формы startcol: endcol, а возвращаемое значение всегда является data.table.с = FALSE больше не нужно динамически выбирать столбцы.Обратите внимание, что x [, cols] эквивалентно x [, ..cols] и x [, cols, с = FALSE] и x [, .SD, .SDcols = cols].

# Case 2 :
aggregate_mtcars<-mtcars_copy[,(get(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,eval(new_col)=sum(carb))] # error
aggregate_mtcars<-mtcars_copy[,c(eval(new_col)=sum(carb))] # Error

mtcars_copy[, new_col, with = FALSE ] # gives a data.table
mtcars_copy[, eval(new_col), with = FALSE ] # this works and create a data.table
mtcars_copy[, eval(new_col), with = TRUE ] # the default that is used here with error
mtcars_copy[, get(new_col), with = TRUE ] # works and gives a vector

# Case 2 solution : affecting values the data.frame way
mtcars_copy[, eval(new_col) ] <- sum(mtcars_copy$carb) # or any vector
mtcars_copy[[eval(new_col)]] <- sum(mtcars_copy$carb) # or any vector
...