От новичка до гуру: Курсы программирования на CyberDuff

R - Как запустить среднее и максимальное значение для разных столбцов data.table на основе нескольких факторов и вернуть исходные имена столбцов

Я меняю свой код R с data.frame + plyr на data.tables, поскольку мне нужен более быстрый и эффективный с точки зрения памяти способ обработки большого набора данных. К сожалению, мои навыки R крайне ограничены, и весь день я бился о стену. Был бы признателен, если бы специалисты ТАК здесь могли просветить.

Мои цели

  • Сводные строки в моей таблице data.table на основе 2 функций - среднего и максимального - выполняются для выбранных столбцов (с именами столбцов, переданными через вектор), в то время как группировка по столбцам также передается через вектор.
  • Результирующее ОУ должно содержать исходные имена столбцов.
  • Не должно не быть ненужного копирования DT для экономии памяти.

Мой тестовый код

DT = data.table( a=LETTERS[c(1,1,1:4)],b=4:9, c=3:8, d = rnorm(6), 
                 e=LETTERS[c(rep(25,3),rep(26,3))], key="a" )

GrpVar1 <- "a"
GrpVar2 <- "e"
VarToMax <- "b"
VarToAve <- c( "c", "d")

То, что я пробовал, но у меня не получилось

DT[, list( b=max( b ), c=mean(c), d=mean(d) ), by=c( GrpVar1, GrpVar2 ) ]  
# Hard-code col name - not what I want

DT[, list( max( get(VarToMax) ), mean( get(VarToAve) )), by=c( GrpVar1, GrpVar2 ) ]  
# Col names become 'V1', 'V2', worse, 1 column goes missing - Not what I want either

DT[, list( get(VarToMax)=max( get(VarToMax) ), 
           get(VarToAve)=mean( get(VarToAve) ) ), by=c( GrpVar1, GrpVar2 ) ]
# Above code gave Error!

Дополнительный вопрос

Основываясь на моем очень ограниченном понимании DT, аргумент with = F должен указывать R на анализ значений VarToMax и VarToAve, но выполнение приведенного ниже кода приводит к ошибке.

DT[, list( max(VarToMax), mean(VarToAve) ), by=c( GrpVar1, GrpVar2 ), with=F ]

# Error in `[.data.table`(DT, , list(max(VarToMax), mean(VarToAve)), by = c(GrpVar1,  : 
#   object 'ansvals' not found
# In addition: Warning message:
# In mean.default(VarToAve) :
#   argument is not numeric or logical: returning NA

Существующие решения SO не могут помочь

Я дошел до этого с помощью решения Аруна, но я очень застрявший. Другое его решение, использующее lapply и .SDcols, включает создание 2 дополнительных DT, что не отвечает моим требованиям к сохранению памяти.

dt1 <- dt[, lapply(.SD, sum), by=ID, .SDcols=c(3,4)]
dt2 <- dt[, lapply(.SD, head, 1), by=ID, .SDcols=c(2)]

Я ТАК запутался в data.table! Любая помощь будет очень признательна!

02.02.2015

Ответы:


1

Вот моя скромная попытка

DT[, as.list(c(setNames(max(get(VarToMax)), VarToMax), 
               lapply(.SD[, ..VarToAve], mean))), 
     c(GrpVar1, GrpVar2)]    
#    a e b c          d
# 1: A Y 6 4 -0.8000173
# 2: B Z 7 6  0.2508633
# 3: C Z 8 7  1.1966517
# 4: D Z 9 8  1.7291615

Или для максимальной эффективности вы можете использовать комбинацию colMeans и eval(as.name()) вместо lapply и get

DT[, as.list(c(setNames(max(eval(as.name(VarToMax))), VarToMax), 
             colMeans(.SD[, ..VarToAve]))), 
     c(GrpVar1, GrpVar2)]   
#    a e b c          d
# 1: A Y 6 4 -0.8000173
# 2: B Z 7 6  0.2508633
# 3: C Z 8 7  1.1966517
# 4: D Z 9 8  1.7291615
02.02.2015
  • Решение colMeans на самом деле может быть не идеальным. См. этот ответ Аруна. 02.02.2015
  • Да, возможно, ты прав. Стоит проверить, что было бы более эффективным с точки зрения памяти для нескольких столбцов - несколько вызовов .SD через lapply (который в основном вызывает весь набор данных несколько раз, а также в настоящее время не оптимизирован) или преобразование в матрицу. 02.02.2015
  • Я предполагаю, что это зависит от реальных данных и (возможно) от того, насколько важна скорость по сравнению с эффективностью памяти. 02.02.2015

  • 2

    Аналогично @David Arenburg, но с использованием .SDcols для упрощения обозначений. Также показываю код до слияния.

    DTaves <- DT[, lapply(.SD, mean), .SDcols = VarToAve, by = c(GrpVar1, GrpVar2)]
    DTmaxs <- DT[, lapply(.SD, max), .SDcols = VarToMax, by = c(GrpVar1, GrpVar2)]
    merge(DTmaxs, DTaves)
    ##    a e b c          d
    ## 1: A Y 6 4  0.2230091
    ## 2: B Z 7 6  0.5909434
    ## 3: C Z 8 7 -0.4828223
    ## 4: D Z 9 8 -1.3591240
    

    В качестве альтернативы вы можете сделать это за один раз, разделив .SD с помощью нотации .. для поиска VarToAve в родительском фрейме .SD (в отличие от столбца с именем VarToAve)

    DT[, c(lapply(.SD[, ..VarToAve], mean), 
           lapply(.SD[, ..VarToMax], max)), 
       by = c(GrpVar1, GrpVar2)]
    ##    a e c          d b
    ## 1: A Y 4  0.2230091 6
    ## 2: B Z 6  0.5909434 7
    ## 3: C Z 7 -0.4828223 8
    ## 4: D Z 8 -1.3591240 9
    
    02.02.2015
    Новые материалы

    Представляем Narwhal Technologies (Nrwl)
    6 декабря 2016 г. Маунтин-Вью, Калифорния С тех пор, как Виктор Савкин и я (Джефф Кросс) присоединились к команде Angular в Google на заре Angular 1, Angular продемонстрировал феноменальный..

    Путь AWS  — «Изучение машинного обучения — 10 начинающих ИИ и машинного обучения на AWS».
    Универсальный ресурсный центр для изучения искусственного интеллекта и машинного обучения. НОЛЬ или ГЕРОЙ, начните свое путешествие здесь. Получите решения и пройдите обучение у экспертов AWS...

    5 простых концепций Python, ставших сложными
    #заранее извините 1) Переменные x = 4 y = 5 Переменная в Python — это символическое представление объекта. После присвоения некоторого объекта переменной Python мы приобретаем..

    «Освоение вероятности: изучение совместной, предельной, условной вероятности и теоремы Байеса —…
    Виды вероятности: Совместная вероятность Предельная вероятность Условная вероятность Диаграмма Венна в вероятностях: В “Set Theory” мы создаем диаграмму Венна...

    Основы Spring: Bean-компоненты, контейнер и внедрение зависимостей
    Как лего может помочь нашему пониманию Когда мы начинаем использовать Spring, нам бросают много терминов, и может быть трудно понять, что они все означают. Итак, мы разберем основы и будем..

    Отслеживание состояния с течением времени с дифференцированием снимков
    Время от времени что-то происходит и революционизирует часть моего рабочего процесса разработки. Что-то более забавное вместо типичного утомительного и утомительного процесса разработки. В..

    Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
    Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..