2015-03-11 9 views
0

Предположим, у меня есть список кадров данных в R.Get строковые имена фреймов данных/объектов в списке

testList <- list(df1, df2, df3) 

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

>> modify <- function(list.of.dfs){ 
    for (df in list.of.dfs){ 
     df$some.new.variable <- some.new.value 

>> df 
>> (returns new df with new variable created) 

Это простой пример; для каждого кадра данных в списке, в кадре данных теперь будет новая переменная с некоторым значением.

Я почти нашел решение. В принципе, он выполняет итерацию через список и создает строку для каждого кадра данных, а затем оценивает его. Но единственная проблема заключается в том, что, когда он создает команду, она будет проходить в версии строки индексной переменной, а не имя фрейма данных:

modify <- function(data.list, functionName){ 
    for(i in 1:length(data.list)){ 
    command <- paste0(varText(data.list), 
         "[[", 
         i, 
         "]] <- ", 
         varText(functionName), 
         "(", 
         varText(data.list), 
         "[[", 
         i, 
         "]])" 
        ) 
    evaluate <- parse(command) 
    print(evaluate) 
    eval(evaluate) 
    } 
    data.list 
} 

где:

varText <- function(object){ 
    deparse(substitute(object)) 
} 

Так Мне нужно найти способ доступа к кадрам данных, потянуть их имена и перебрать список команд с именами этих фреймов данных.

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

... если кто-то не знает лучшего решения для этого.

Изменить: воспроизводимый пример

Предположим, я создаю два кадра данных и добавить их в тот же список:

df1 <- data.frame(rnorm(100), rnorm(100)) 
df2 <- data.frame(rnorm(100), rnorm(100)) 
test.list <- list(df1, df2) 

И создать функцию, которая тривиальным редактирует кадр данных, который передается в :

testFunction <- function(data.frame){ 
    data.frame$new.variable <- 0 
} 

Тогда я могу использовать lapply как предложено в ответ:

lapply(test.list, testFunction) 

Что возвращает список.

Однако, если вы звоните df1 или df2, они остаются без изменений. Созданы модифицированные версии df1 и df2, но они сохраняются в списке lapply.

Я хочу просто быть в состоянии типа

df1 
df2 

И у них быть изменены.

Есть ли способ сделать это, чтобы вам не нужно было назначать элементы списка lapply создает имена переменных, к которым вы хотите получить доступ?

Много, очень ценим!

+0

Можете ли вы привести пример того, как вы бы назвали 'modify' и что вы ожидаете от него. – mnel

+0

Спасибо за предложение @mnel. Я добавил один - дайте мне знать, если это не ясно. – xenophanes

ответ

1

Если я правильно понял вас, вы хотите применить функцию к списку кадров данных?

В данном случае lapply() - ваш друг и будет намного эффективнее, чем цикл for().

Основываясь на своем пересмотренном примере, попробовать что-то вроде:

# data 
df1 <- data.frame(rnorm(100), rnorm(100)) 
df2 <- data.frame(rnorm(100), rnorm(100)) 
test.list <- list(df1, df2) 

# function 
out.list <- lapply(test.list, function(x) {x$.new.variable <- 0; x}) 

# name the df's in the list and check the output 
names(out.list) <- c("df1", "df2") 
str(out.list) 

это будет применить функцию к каждому объекту в списке, и возвращает результаты в виде списка [с @ thelatemail предложено, редактировать].

Если затем вы хотите получить доступ к измененному dataframes вы можете просто назвать их по имени:

out.list$df1 

Или, если вы хотите вернуть ФР в глобальную среду, вы можете использовать следующую при условии наличия названный df, используя вышеуказанный шаг:

list2env(out.list ,.GlobalEnv) 

Это должно делать то, что вам нужно.

+1

Не совсем, вам также нужно вернуть объект после его изменения или иначе будет возвращено только новое значение, например: 'lapply (list (data.frame (one = 1), data.frame (two = 2)) , function (x) {x $ new <- 1; x}) ' – thelatemail

+0

Привет @AJD, большое вам спасибо за помощь. Я добавил воспроизводимый пример - ваш ответ почти у вас. Дайте мне знать, если я могу отредактировать его вообще, чтобы сделать его более ясным; Я новичок в Stack Overflow! – xenophanes

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