Как я могу определить столбец R data.table / data.frame из параметра функции?

Я создал функцию в пакете R, которая принимает несколько аргументов. Один из этих аргументов - имя столбца для таблицы R data.table.

Допустим, я хотел создать столбец со всеми значениями 42. Для R data.table dt я бы сделал:

dt[, column_name:=42]

Для R data.frame я бы сделал:

df$column_name = 42

Я бы хотел, чтобы функция принимала в качестве аргумента что-то, что определяло бы column_name. Например, функция func, вызываемая

func(dt, col='hey')

передаст hey как новое имя столбца data.table.

Вот конкретный пример

renamer = function(colname, dt){
    ## do calculations on dt
    dt[, colname:= 42]
}

Если я вызову функцию renamer(colname = 'foo', dt=dt), имя результирующего столбца все равно будет colname, а не переданное мной значение «foo».

В новом столбце должна быть строка "foo".

Как я мог это сделать? Я также пробовал с R data.frame или пробовал что-то с

setnames(dt, "oldname", "newname")

Обновлено: Я думаю, этот вопрос следует прояснить:

Вот таблица data.table:

> library(data.table)
> DT = data.table(ID = c("b","b","b","a","a","c"), a = 1:6, b = 7:12, c = 13:18)
> DT
   ID a  b  c
1:  b 1  7 13
2:  b 2  8 14
3:  b 3  9 15
4:  a 4 10 16
5:  a 5 11 17
6:  c 6 12 18

Я хотел бы создать функцию, в которой новое имя столбца будет строкой, которую пользователь передает.

например

colnamer = function(newcolumname, datatable){
    ## do calculations on dt
    ## create a column with whatever string is passed via 'newcolumnname'
}

Если пользователь вызывает colnamer('foobar', DT), я бы хотел, чтобы результат был

> DT
   ID a  b  c  foobar
1:  b 1  7 13   ...
2:  b 2  8 14   ...
3:  b 3  9 15   ...
4:  a 4 10 16   ...
5:  a 5 11 17   ...
6:  c 6 12 18   ...

Не совсем уверены, чего хотите? Вы хотите, чтобы имя столбца для colname в функции renamer изменилось или вы хотите изменить содержимое colname? В последнем случае я думаю, что это сработает; dt[, get(colname) := 42]

tstev 29.05.2018 22:19

@tstev Я хочу, чтобы новый столбец назывался строкой, которую пользователь передает в функцию. например в приведенном выше renamer(colname = 'foo', dt=dt) новый столбец будет foo

ShanZhengYang 29.05.2018 22:20

@tstev У меня ошибка с get(colname) - Error in get(colname) : object 'foo' not found

ShanZhengYang 29.05.2018 22:21

как dt[[colname]] <- 42?

Moody_Mudskipper 29.05.2018 22:25

Я не эксперт по data.table, но считаю, что линия в renamer должна быть dt[, (colname) := 42].

markus 29.05.2018 22:28

Не обращайте внимания на мою первую. set(dt, j = colname, value = 42)

tstev 29.05.2018 22:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
170
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

РЕДАКТИРОВАТЬ: изменен на новый воспроизводимый пример OP с двумя предложениями, которые работали согласно формулировке проблемы OP;

library(data.table) 
DT <- data.table(ID = c("b","b","b","a","a","c"), 
                 a = 1:6, b = 7:12, c = 13:18)

colnamer1 <- function(newcolumname, datatable) {
  ## do calculations on dt
  ## create a column with whatever string is passed via 'newcolumnname'
  set(datatable, j = newcolumname, value = 42)
}

colnamer2 <- function(newcolumname, datatable) {
  ## do calculations on dt
  ## create a column with whatever string is passed via 'newcolumnname'
  dt[, (newcolumname) := 42]
}

colnamer1("name_me", DT)
colnamer2("name_me_too", DT)
DT
#    ID a  b  c name_me name_me_too
# 1:  b 1  7 13      42          42
# 2:  b 2  8 14      42          42
# 3:  b 3  9 15      42          42
# 4:  a 4 10 16      42          42
# 5:  a 5 11 17      42          42
# 6:  c 6 12 18      42          42

Возможное решение для data.frame? Хотя с тех пор, как я принял data.table, мой data.frame-ing немного заржавел. Возможно, есть более элегантное решение вашей проблемы, когда дело касается data.frame.

df <- data.frame(ID = c("b","b","b","a","a","c"), 
                 a = 1:6, b = 7:12, c = 13:18)
df_colnamer <- function(name_me, df) {
  new_df <- df
  new_df[[name_me]] <- 42
  new_df
}
new_df <- df_colnamer("foo", df)
new_df
#   ID a  b  c foo
# 1  b 1  7 13  42
# 2  b 2  8 14  42
# 3  b 3  9 15  42
# 4  a 4 10 16  42
# 5  a 5 11 17  42
# 6  c 6 12 18  42

Спасибо, в этом есть смысл. Интересно - как бы это сделать, если бы это был data.frame? Помимо преобразования в data.table ...

ShanZhengYang 29.05.2018 23:15

@ShanZhengYang, тогда предложение @Moody_Mudskipper сработает. Но преимущество data.table в том, что он может делать это по ссылке в памяти без необходимости создавать копию.

tstev 29.05.2018 23:21

Опечатка в colnamer2. Должен быть datatable[, (newcolumname) := 42]

ShanZhengYang 30.05.2018 20:48

Другие вопросы по теме