2013-03-30 5 views
1

У меня есть 21 глобальная переменная окружения, каждая из которых содержит большое количество данных. Я хочу получить доступ к этим переменным по ссылке внутри функций, но я хочу параметризовать их имена, например, если у меня есть SPdata, NEdata, FRdata и т. Д .... 21 переменные, я хотел бы знать, как обращаться к ним внутри функций, передавая только «название страны» (то есть «SP», «NE», «FR» и т. д.) без необходимо создать копию (потому что каждый из них имеет размер более 300 мегабайт). Кажется, что получается копия (неэффективна для мой размер данных). Могу ли я это сделать? Я в настоящее время использую получает везде такМогу ли я получить() глобальную переменную среды R по ссылке?

cData <- get(paste(cCode, "data", sep = "")) 

Да, я знаю, что я должен поместить их всех в список в глобальном окр, но это слишком поздно, и я не» t хочу реорганизовать весь код. Просто мои «получает» становятся неэффективными, а множественный доступ в циклах может быть медленным. r пример доступа к каждой переменной, как если бы она была в списке?

Я должен был пойти с countryData = list (SPdata, NEdata, FRdata..etc), обратившись к ним с помощью countryData [[paste (cCode, "data", sep = "")]], но уже слишком поздно.

Я должен был добавить, что я намерен изменить некоторые значения внутри функций и get() копирует при изменении, как видно из разных адресов ниже.

> .Internal(inspect(a)) 
@101b7bcf8 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 1 
> g <- function() {x <- get("a"); x; x <- 2; .Internal(inspect(x))} 
> g() 
@101cea648 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 2 
> 
+0

В примере. Внутренний (проверка (x)) выдается после утверждения нового значения 'x', и именно это вызвало новый адрес, а не' get'. –

ответ

5

get не генерирует копии. Например, в приведенном ниже коде мы видим, что x является не копией a.1, так как ее с тем же адресом, то есть на 0x00000000077a0010.

> a.1 <- 1:1000000 
> .Internal(inspect(a.1)) 
@0x00000000077a0010 13 INTSXP g0c7 [NAM(1)] (len=1000000, tl=0) 1,2,3,4,5,... 
> g <- function() { x <- get("a.1"); .Internal(inspect(x)); max(x) } 
> g() 
@0x00000000077a0010 13 INTSXP g0c7 [NAM(2)] (len=1000000, tl=0) 1,2,3,4,5,... 
[1] 1000000 

Если вы изменяете переменную (добавление является типом модификации), то она будет скопирована. Здесь x начал в 0x00000000075b95d8, но после того, как модифицируются был скопирован 0x000000000744d8e0 и после того, как добавляется к скопирована еще раз на этот раз 0x000000000754c5e8:

> n <- 10000 
> x <- 1:n 
> .Internal(inspect(x)) 
@0x00000000075b95d8 13 INTSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,... 
> f <- function() { 
+ .GlobalEnv$x[[n]] <- 0 
+ .Internal(inspect(x)) 
+ x <<- c(x, 0) 
+ .Internal(inspect(x)) 
+ } 
> f() 
@0x000000000744d8e0 14 REALSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,... 
@0x000000000754c5e8 14 REALSXP g0c7 [NAM(1)] (len=10001, tl=0) 1,2,3,4,5,... 

Выше мы изменили глобальную переменную внутри функции, но даже если бы мы имели сделал это вне функции, которую он все еще был бы скопирован.

+0

Я изменил мой вопрос, который был неполным. Мне нужно внести небольшие изменения (добавляет). Я знаю, что есть хаос среды для прохождения по ссылке, но я бы предпочел избежать хаков. –

+0

См. Дополнительные замечания в ответе. –

4

Быстрые из них:

  • R семантика 'копирование при записи', так что если вы не изменить содержание этих переменных, никакие копии не делаются

  • R имеет профилирование памяти, действительно ли вы уверены, что копии сделаны? См. «Написание R-расширений» для основ профилирования памяти.

  • Если вы действительно уверены, что они копируются, вы можете предотвратить это, используя внешнее использование указателя, либо используя объекты XPtr, либо используя оболочки, развертывающие внешние указатели, такие как bigmemory.

+0

Хорошо, я посмотрю. Я предположил, что копии сделаны, потому что если я это сделаю: dd <- 1; ee <- get ("dd"); ee <- 2, то dd по-прежнему равно 1. Также мне нужно написать эти переменные, поэтому я сейчас пишу копии, а затем назначаю их для перезаписывания оригиналов. –

+0

Dirk: не будет ли '<-' функцией, ответственной за копию? –

+0

Нет, копирование при записи - просто переназначение работ со ссылкой. См. Ответ Gabor для деталей - если вы сделали «a.2 <- a.1», вы все равно использовали бы тот же адрес памяти. –

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