2015-02-05 2 views
0

Помощник R для назначения говорит: «Назначение не отправляет методы назначения, поэтому его нельзя использовать для установки элементов векторов, имен, атрибутов и т. Д.». Опустите вниз, в примерах, мы показали:Как использовать назначение для изменения части вектора в R?

a <- 1:4 
assign("a[1]", 2) 
a[1] == 2   # FALSE 
get("a[1]") == 2 # TRUE 

Я хотел бы знать, как решить эту проблему, что этот пример указывает, - учитывая символьная строка, представляющая часть вектора или данных кадра, как я могу назначить в это место? Я могу принести значения:

x <- "a[1]" 
eval(parse(text=x)) # 1 

и, конечно, я могу назначить в часть вектора

a[1:2] <- c(0,0) 

так как я положил их вместе, если я начинаю с символьной строки?


Спасибо LauriK, но моя трудность заключается в том, что строка является «[1: 2]», так что даже прибудет потерпят неудачу. Я объясню аргументы, которые заставили меня задать этот вопрос.

У меня есть два кадра данных, один, как это:

> df 
    Fiscal Year Num Deferrals 1 Yr Prob 
1  2015    0  100% 
2  2016    0  100% 
3  2017   65   98% 
2 Year Total    65   n/a 
2 Year Average   32   n/a 

и еще так:

> sv 
nDeferrals nSmallDeferrals oneYrProb 
      0     0  1.0000 
      0     0  1.0000 
     65    63  .9797 

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

"df$'1 Yr Prob'[1:3]" 
"sv$oneYrProb" 

Пока «ДФ $ '1 Yr Prob [1: 3]» не изменится, я буду переписывать его с каким-либо значением „Sv $ oneYrProb“ является в будущем. Я спасаю имена двух переменных, и значение первого в то время она замерзает:

freeze <- function(R_name, saved_name) { 
    frozen <- new.env() 
    R_value <- eval(parse(text=R_name)) 
    with(frozen, assign(R_name, list(R_name, R_value, saved_name))) 
    save(frozen, file="frozen.RData") 
} 

В результате «замороженная» среда содержит переменные, которые выглядят следующим образом:

> frozen$"df$'1 Yr Prob'[1:3]" 
[[1]] 
[1] "df$\"1 Yr Prob\"[1:3]" 

[[2]] 
[1] "100% "100%" "98%" 

[[3]] 
[1] "sv$oneYrProb" 

Итак, у меня есть символьные строки, представляющие два объекта в тесте, и значение первого в момент его замораживания. .
я могу получить значение объектов - с помощью «Eval (разбор» -, но я не знаю, как хранить обратно в первый у меня есть:

processFreezeList <- function() { 
    load("frozen.RData", envir=.GlobalEnv) 
    variables <- ls(frozen) 
    for (v in variables) { 
     temp <- get(v, frozen) 
     R_name <- temp[[1]] 
     R_value <- temp[[2]] 
     saved_name <- temp[[3]] 
     if (all(eval(parse(text=R_name)) == R_value)) 
      assign(R_name, eval(parse(text=saved_name)), envir=.GlobalEnv) 
    } 
} 

Вместо того, чтобы писать над первым объект, правопреемник создает новую переменный:

"df$/"1 Yr Prob/"[1:3]" 

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

+5

Почему, по-вашему, вам нужно это делать? Вероятно, вы этого не сделаете. Если вы используете 'eval()' или 'assign()', почти всегда есть «лучший», более «R-образный» способ сделать что-то. – MrFlick

ответ

0

У меня есть ответ на проблему, которая мотивировала мой вопрос, и я думаю, что это можно обобщить. Это выглядит так:

a <- c(1,1,1) 
b <- c(2,2,2) 
x <- "a[1]" 
y <- "b[1]" 
eval(parse(text=paste(x,"<-",y) 
a 
[1] 2 1 1 

Другими словами, приведите само присваивание в строку и оцените это.

+1

@RichardScriven Я хочу поблагодарить LauriK и RichardScriven за то, что помог мне разобраться в этом. – user3517677

1

Если я правильно вас понимаю, тогда вы хотите изменить части векторов, зная только имя вектора в виде строковой переменной.Попробуйте что-то вроде этого:

> (a <- letters[1:5]) 
[1] "a" "b" "c" "d" "e" 
> x <- "a" 
> var.x <- get(x) 
> var.x[1:2] <- c(0,0) 
> assign(x, var.x) 
> a 
[1] "0" "0" "c" "d" "e" 
+0

@ RichardScriven поясните пожалуйста. Я добавила первую строчку в свой ответ, и она работает как ответ на исходный вопрос. Теперь, когда я увидел, что исходный вопрос сильно отредактирован, я рассмотрю его через несколько часов и посмотрю, смогу ли я найти лучший ответ. – LauriK

+1

Ну, исходный ответ вызвал ошибку в 'get (x)', потому что 'a' не был определен. И, следовательно, вызвана ошибка в каждом вызове. –

+0

@LauriK Я все еще здесь. Моя строка не похожа на «а». Это один из многих вариантов «a [1]», и get («a [1]») не работает. – user3517677

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