Передача целочисленных переменных в виде столбцов в функции, используемых в таблице данных [duplicate]

Если вы хотите, чтобы сервер MySQL решал набор символов, а не PHP как клиент (старое поведение, предпочтительнее, на мой взгляд), попробуйте добавить skip-character-set-client-handshake к вашему my.cnf в [mysqld] и перезапустить mysql.

Это может вызвать проблемы, если вы используете что-либо, кроме UTF8.

25
задан attitude_stool 5 June 2013 в 16:29
поделиться

3 ответа

Да, вы здесь под вопросом:

Я понимаю, что более эффективно перебирать вектор имен столбцов, используя := для назначения:

for (col in paste0("V", 20:100)) dt[, col := sqrt(dt[[col]]), with = FALSE]

Кроме того: обратите внимание, что новый способ сделать это:

for (col in paste0("V", 20:100))
  dt[ , (col) := sqrt(dt[[col]])]

, потому что with = FALSE было непросто прочитать, относится к LHS или RHS :=. Конец.

Как вы знаете, это эффективно, потому что каждый столбец один за другим, поэтому рабочая память нужна только для одного столбца за раз. Это может сделать разницу между работой и ошибкой с ошибкой ошибки вне памяти.

Проблема с lapply в RHS := заключается в том, что RHS (lapply ) оценивается первым; то есть результат для 80 столбцов. Это 80 колонок стоит новой памяти, которая должна быть распределена и заполнена. Таким образом, для достижения этой цели вам понадобится бесплатная операционная память 80 столбцов. Это использование ОЗУ доминирует против мгновенной операции назначения ( plonking ) этих 80 новых столбцов в слоты указателя столбца data.table.

Как отметил @Frank, если у вас есть много столбцов (скажем, 10 000 или более), тогда небольшие накладные расходы на отправку методу [.data.table начинают складываться). Чтобы устранить эти служебные данные, которые есть data.table::set, которые под ?set описываются как «закодированные» :=. Я использую цикл for для этого типа операции. Это самый быстрый способ и довольно легко писать и читать.

for (col in paste0("V", 20:100))
  set(dt, j = col, value = sqrt(dt[[col]]))

Хотя с 80 столбцами это вряд ли имеет значение. (Обратите внимание, что это может быть более распространено для цикла set для большого количества строк, чем большое количество столбцов.) Однако цикл set не решает проблему повторной ссылки на имя символа dt, которое вы упомянули в вопросе:

Мне это не нравится, потому что мне не нравится ссылаться на data.table в выражении aj.

Согласовано. Поэтому лучше всего вернуться к вашему циклу :=, но вместо этого используйте get.

for (col in paste0("V", 20:100))
  dt[, (col) := sqrt(get(col))]

Однако я боюсь, что использование get в j может быть неэффективным. Для этого необходим бенчмаркинг, # 1380 . Кроме того, возможно, смущает использование get() в RHS, но не на LHS. Чтобы решить, что мы можем сахара LHS и разрешить get(), # 1381 :

for (col in paste0("V", 20:100))
  dt[, get(col) := sqrt(get(col))]

Кроме того, возможно value of set можно запустить в пределах область действия DT, # 1382 .

for (col in paste0("V", 20:100))
  set(dt, j = col, value = sqrt(get(col))
30
ответ дан Henrik 4 September 2018 в 09:01
поделиться

Они должны работать, если вы хотите ссылаться на столбцы по имени строки:

n = paste0("V", 20:100)
dt[, (n) := lapply(n, function(x) {sqrt(get(x))})]

или

dt[, (n) := lapply(n, function(x) {sqrt(dt[[x]])})]
14
ответ дан eddi 4 September 2018 в 09:01
поделиться

Это то, что вы ищете?

dt[ , names(dt)[20:100] :=lapply(.SD, function(x) sqrt(x) ) , .SDcols=20:100]

Я слышал, что использование .SD не так эффективно, потому что оно делает копию таблицы заранее, но если ваша таблица не является " t огромный (очевидно, это относительно зависит от ваших системных спецификаций). Я сомневаюсь, что это будет иметь большое значение.

7
ответ дан Simon O'Hanlon 4 September 2018 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: