Как ускорить за столбец итерации - PullRequest
1 голос
/ 19 апреля 2019

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

Давайте возьмем mtcars в качестве примера

У меня такое ощущение, что вы можете придерживаться пути .SD, но предоставить дополнительные аргументы и сделать это гораздо более эффективным ...

require(data.table)
dt = data.table(mtcars)

#looping through columns of mtcars...
cols = c('mpg', 'hp', 'disp')
dt[,lapply(.SD, function(x) x/mean(x)), .SDcols=cols]

# But actually I want to devide x by the mean of x where am==1

# Now I am doing this...

specificMean= function(DT) {
  x = DT$feature
  xAM = DT[AM==1]$feature
  MEAN = mean(xAM, na.rm=TRUE)
  x = x/MEAN    
  return(x)
}

dt[,(cols):=lapply(cols, function(x) specificMean(data.table(feature=get(x), AM=am))), .SDcols=cols]
print(dt)

У меня такое ощущение, что это намного медленнее, потому что он выполняетфункция data.table () в каждой итерации ...

Векторизованное решение было бы неплохо ..

Ответы [ 3 ]

1 голос
/ 22 апреля 2019

Возможный подход:

dt[, (cols) := mapply(`/`, .SD[,-"am"], lapply(.SD[am==1, -"am"], mean), SIMPLIFY=FALSE), 
    .SDcols=c("am", cols)]
0 голосов
/ 26 апреля 2019

system.time(dt[,lapply(cols, function(x) specificMean(data.table(feature=get(x), AM=am))), .SDcols=cols])

пользовательская система прошла 0,010 0,000 0,005

эффективный способ с использованием двух циклов благодаря @ chinsoon12

system.time(dt[,mapply(`/`, .SD[,-"am"], lapply(.SD[am==1, -"am"], mean), SIMPLIFY=FALSE), .SDcols=c("am", cols)])

пользовательская система прошла 0,001 0,000 0,001

Эффективный способ выиграть с помощью одного цикла благодаря @ Cole

system.time(dt[,.SD / lapply(.SD[am == 1], mean, na.rm = TRUE), .SDcols = cols])

пользовательская система прошла 0,001 0,000 0,001

0 голосов
/ 21 апреля 2019

Редактировать: Это похоже на тот же результат, что и ваш.

library(data.table)

dt = data.table(mtcars)
cols = c('mpg', 'hp', 'disp')

dt[, (cols) := .SD / lapply(.SD[am == 1], mean, na.rm = TRUE), .SDcols = cols]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...