Эффективность программного назначения в R

Таким образом, у меня есть скрипт для импорта большого количества данных, хранящихся в нескольких текстовых файлах. В одном файле не все строки должны быть помещены в одну и ту же таблицу (DF теперь переключается на DT), поэтому для каждого файла я выбираю все строки, принадлежащие одному и тому же DF, get DF и assign к нему ряды.

В первый раз, когда я создаю DF с именем, скажем, table1, я делаю:

name <- "table1" # in my code the value of name will depend on different factors
                 # and **not** known in advance
assign(name, someRows)

Затем во время выполнения мой код может найти (в других файлах) другие строки для помещения во фрейм данных table1, поэтому:

name <- "table"
assign(name, rbindfill(get(name), someRows))

Мой вопрос: является ли assign(get(string), anyObject) лучшим способом для выполнения присваивания программно? Спасибо

РЕДАКТИРОВАТЬ:

вот упрощенная версия моего кода: (каждый элемент в dataSource является результатом read.table(), поэтому один текстовый файл)

set.seed(1)
#
dataSource <- list(data.frame(fileType = rep(letters[1:2], each=4),
                              id       = rep(LETTERS[1:4], each=2),
                              var1     = as.integer(rnorm(8))),
                   data.frame(fileType = rep(letters[1:2], each=4),
                              id       = rep(LETTERS[1:4], each=2),
                              var1     = as.integer(rnorm(8))))
#                   #                                                                                          #
#                          
library(plyr)
#
tablesnames <- unique(unlist(lapply(dataSource,function(x) as.character(unique(x[,1])))))
for(l in tablesnames){
  temp <- lapply(dataSource, function(x) x[x[,1]==l, -1])
  if(exists(l)) assign(l, rbind.fill(get(l), rbind.fill(temp))) else assign(l, rbind.fill(temp))
}
#
#            
# now two data frames a and b are crated
#
#
# different method using rbindlist in place of rbind.fill (faster and, until now, I don't # have missing column to fill)
#
rm(a,b)
library(data.table)
#
tablesnames <- unique(unlist(lapply(dataSource,function(x) as.character(unique(x[,1])))))
for(l in tablesnames){
  temp <- lapply(dataSource, function(x) x[x[,1]==l, -1])
  if(exists(l)) assign(l, rbindlist(list(get(l), rbindlist(temp)))) else assign(l, rbindlist(temp))
}

person Michele    schedule 14.05.2013    source источник
comment
Я не очень понимаю ваш вопрос, но скажу, что вам, вероятно, не следует использовать ни get, ни assign. Если бы вы привели воспроизводимый пример, люди могли бы показать вам лучший способ работы с вашими данными.   -  person Roland    schedule 14.05.2013
comment
@Roland Привет, я отредактировал свой вопрос. Что вы на самом деле не понимаете?   -  person Michele    schedule 14.05.2013
comment
@Roland, воспроизводимый пример готов!   -  person Michele    schedule 14.05.2013
comment
В том же духе, что и ответ Пола, я думаю: избегайте динамического роста чего-либо, связывая его в цикле.   -  person Frank    schedule 14.05.2013
comment
@ Фрэнк, что значит? ты полностью прочитал мой пост?   -  person Michele    schedule 14.05.2013
comment
Я имею в виду, что если вы последуете его совету (работая со списком вместо цикла), вы сможете избежать rbindlist/rbindfill, а также assign и get. Ваш rbinds и двойное копирование в temp, вероятно, очень важны для производительности. Я могу ошибаться; Я не компьютерщик. Извините за неясность.   -  person Frank    schedule 14.05.2013
comment
@Frank Спасибо за ответ. Вы правы, и я действительно понимаю, что вы и @Paul имеете в виду. Но проблема в том, что у меня есть в разных текстовых файлах фрагменты того, что должно быть (в конце процесса импорта) одним data.frame или data.table. Имеет ли это смысл? (temp — это список всех импортированных текстовых файлов)   -  person Michele    schedule 14.05.2013
comment
Я думаю, что я бы подошел к вашей проблеме, сначала придумав список имен допустимых файлов, а затем do.call(rbind,lapply(my_list,get)) или что-то подобное. На самом деле, я довольно часто делал это (с экспортированными из SAS CSV-файлами) в последнее время, связывая воедино серию наборов данных с немного разными переменными, собираемыми каждый год. Если мы все еще неправильно понимаем ваш вопрос, может быть, вы могли бы попробовать разделить его на более мелкие вопросы?   -  person Frank    schedule 14.05.2013
comment
@Frank, спасибо, ваш комментарий начинает выглядеть как правильный ответ :-). Извините, я думал, что это обычная задача, с которой сталкиваются люди, но я просто неправильно предположил.. Я попытаюсь переписать вопрос намного яснее.   -  person Michele    schedule 14.05.2013
comment
На самом деле это очень распространенная задача, и предложение в моем ответе является эффективным способом ее решения.   -  person Paul Hiemstra    schedule 14.05.2013
comment
@PaulHiemstra Спасибо, но я все еще думаю, что вы немного упускаете мою мысль. Я не могу брать txt-файлы и запихивать их сразу в один df как есть. Как я уже сказал, я думал, что понял, я перепишу вопрос, моя вина.   -  person Michele    schedule 14.05.2013


Ответы (1)


Я бы рекомендовал использовать имя list и пропустить использование assign и get. Многие интересные функции R (например, lapply) очень хорошо работают со списками и не работают с использованием assign и get. Кроме того, вы можете легко передавать списки в функцию, в то время как это может быть несколько громоздко с группами переменных в сочетании с assign и get.

Если вы хотите прочитать набор файлов в один большой data.frame, я бы использовал что-то вроде этого (при условии, что csv похож на текстовые файлы):

library(plyr)
list_of_files = list.files(pattern = "*.csv")
big_dataframe = ldply(list_of_files, read.csv)

или если вы хотите сохранить результат в списке:

big_list = lapply(list_of_files, read.csv)

и, возможно, используйте rbind.fill:

big_dataframe = do.call("rbind.fill", big_list)
person Paul Hiemstra    schedule 14.05.2013
comment
Я добавляю пример... одну секунду - person Michele; 14.05.2013
comment
Вы проверили мою правку? Я знаю, что вы говорите, это очевидно.. но я не думаю, что это применимо в моем случае.. - person Michele; 14.05.2013
comment
@ Мишель Возможно, это слишком очевидно. Он предлагает вам назначать имена в списке и ссылаться на него, а не назначать имена в глобальной среде. Читая ваш код, нет причин, по которым вы не можете использовать список. - person Matthew Lundberg; 14.05.2013
comment
@MatthewLundberg, причина в том, что я хотел бы, чтобы все эти небольшие фрагменты, импортированные из разных текстовых файлов, находились в одном одном фрейме данных. Имеет ли это смысл? - person Michele; 14.05.2013
comment
Если вы хотите, чтобы они были в одном кадре данных, вы можете просто добавить отдельные наборы данных, например. используя rbind. - person Paul Hiemstra; 14.05.2013
comment
Пожалуйста, внимательно прочитайте мой вопрос. Я сказал: в одном файле не все строки должны быть помещены в одну и ту же таблицу. - person Michele; 14.05.2013
comment
Затем либо используйте rbind.fill, либо сохраните данные в списке. - person Paul Hiemstra; 14.05.2013
comment
Я уже использую rbind.fill..., чтобы вставить в df все элементы списка с именем temp, который содержит текстовые файлы (после фильтрации нужных мне строк) в своих элементах. - person Michele; 14.05.2013
comment
Тогда я бы порекомендовал вам отказаться от чтения на основе assign и переключиться на lapply + rbind.fill. - person Paul Hiemstra; 14.05.2013
comment
Я помещаю образец данных в свой вопрос. Могу ли я увидеть ваш метод в действии? Я имею в виду, не могли бы вы отредактировать свой ответ, используя фиктивные данные, которые я дал в вопросе. Иначе будет слишком болтливо :-) - person Michele; 14.05.2013