2017-02-07 3 views
1

Первый вопрос, дайте мне знать, если в комментариях, пожалуйста, укажите больше информации или фона.Использование функции data.table в lapply в списке с элементами data.frames (Ответ = setDT)

Многие ответы здесь и в других случаях касаются вызова lapply в функции data.table. Я хочу сделать наоборот, что на бумаге должно быть легко lapply(list.of.dfs, fun(x) x), но я не могу заставить его работать с функциями data.table.

У меня есть список, который содержит несколько data.frames с теми же столбцами, но с разным количеством строк. Это происходит из результатов нескольких сценариев моделирования, поэтому их нужно обрабатывать отдельно, а не rbind'ed.

#sample list of data.frames 
    scenarios <- replicate(5, data.frame(a=sample(letters[1:4],10,T), 
           b=sample(1:2,10,T), 
           x=sample(1:10, 10), 
           y =runif(10)), simplify = FALSE) 

Я хочу добавить столбец в каждый элемент, который является суммой x/y по a и b.
Из data.table документации в примерах раздела процесс, чтобы сделать это за один data.frame следующий (поиск: добавить новый столбец со ссылкой на группу на странице дока):

test <- as.data.table(scenarios[[1]]) #must specify data.table class 
test[, newcol := sum(x/y), by = .(a , b)][] 

Я хочу использовать lapply, чтобы сделать то же самое для каждого элемента в списке сценариев и вернуть список. Моя последняя попытка:

lapply(scenarios, function(i) {as.data.table(i[, z := sum(x/y), by=.(a,b)]); i})

, но я получаю ошибку unused argument (by = .a,b))

После заливки на результаты этого и других сайтов я был не в состоянии решить эту проблему. Я уверен, что есть что-то, что я не понимаю о вызове анонимных функций и/или использовании функции data.table. Это один из тех случаев, когда вы используете [как функцию? Или, возможно, моя as.data.table неуместна.

This answer был шагом в правильном направлении (я думаю), он охватывает использование fun (x) {...; x} использовать анонимную функцию и вернуть x.

Спасибо!

ответ

1

Здесь вы можете использовать setDT.

scenarios <- lapply(scenarios, function(i) setDT(i)[, z := sum(x/y), by=.(a,b)]) 

scenarios[[1]] 
    a b x   y   z 
1: c 2 2 0.87002174 2.298793 
2: b 2 10 0.19720775 78.611837 
3: b 2 8 0.47041670 78.611837 
4: b 2 4 0.36705023 78.611837 
5: a 1 5 0.78922686 12.774035 
6: a 1 6 0.93186209 12.774035 
7: b 1 3 0.83118438 3.609307 
8: c 1 1 0.08248658 30.047494 
9: c 1 7 0.89382050 30.047494 
10: c 1 9 0.89172831 30.047494 

Использование as.data.table, синтаксис будет

scenarios <- lapply(scenarios, function(i) {i <- as.data.table(i); i[, z := sum(x/y), 
                    by=.(a,b)]}) 

, но это не рекомендуется, поскольку это создаст дополнительную копию, которую избегают setDT.

+0

Большое вам спасибо! Я знал, что для этого должен быть инструмент. +1 –

+0

Спасибо за разъяснение @Frank. Точка с запятой просто «делает это и переходит к следующему»? –

+0

@JGiancarlo Точка с запятой просто «сделайте это, а затем сделайте это другое». Это точно так же, как писать каждую команду на отдельной строке, насколько я знаю. – Frank

 Смежные вопросы

  • Нет связанных вопросов^_^