Преобразовать строку в имя переменной


100

Я использую R для анализа списка строк в форме:

original_string <- "variable_name=variable_value"

Сначала я извлекаю имя и значение переменной из исходной строки и конвертирую значение в числовой класс.

parameter_value <- as.numeric("variable_value")
parameter_name <- "variable_name"

Затем я хотел бы присвоить значение переменной с тем же именем, что и строка parameter_name.

variable_name <- parameter_value

Каковы функции для этого?

Ответы:


122

assign - это то, что вы ищете.

assign("x", 5)

x
[1] 5

но покупатель остерегается.

См. R FAQ 7.21 http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f


«Покупатель, будьте осторожны» - это довольно грубый способ сказать, что вам почти никогда не следует этого делать, потому что это почти никогда не является хорошим решением данной проблемы.
Конрад Рудольф,

67

Вы можете использовать do.call:

 do.call("<-",list(parameter_name, parameter_value))

11
+1 за размышления. Люди (включая меня) обычно забывают, что <-это сама функция.
Роб


20

используйте x=as.name("string") вы можете использовать затем использовать xдля ссылки на переменную со строкой имени.

Я не знаю, правильно ли он отвечает на ваш вопрос


2
x=as.symbol("string")
Энрике Перес Эрреро

18

Функция, которую вы ищете get():

assign ("abc",5)
get("abc")

Подтверждение идентичности адреса памяти:

getabc <- get("abc")
pryr::address(abc) == pryr::address(getabc)
# [1] TRUE

Ссылка: R FAQ 7.21 Как преобразовать строку в переменную?


1
Большой! Это самый краткий ответ, который я нашел. Есть ли такой же краткий способ сделать обратное? просто какx <- 42; deparse(substitute(x))
Miao Cai

10

strsplitдля анализа вашего ввода и, как упоминал Грег, assignдля присвоения переменных.

original_string <- c("x=123", "y=456")
pairs <- strsplit(original_string, "=")
lapply(pairs, function(x) assign(x[1], as.numeric(x[2]), envir = globalenv()))
ls()

5

assignэто хорошо, но я не нашел функции для возврата к переменной, которую вы создали в автоматическом скрипте. ( as.nameпохоже, работает наоборот). У более опытных программистов, несомненно, будет лучшее решение, но это решение работает и, возможно, немного юмористично, поскольку заставляет R писать код для себя для выполнения.

Скажем, я только что присвоил x( var.name <- "x"; assign(var.name, 5)) значение 5 и хочу изменить это значение на 6. Если я пишу сценарий и не знаю заранее, каким будет имя переменной ( var.name) (что, кажется, является точкой assignфункция), я не могу просто сказать, x <- 6потому что var.nameмогло быть "y". Итак, я делаю:

var.name <- "x"
#some other code...
assign(var.name, 5)
#some more code...

#write a script file (1 line in this case) that works with whatever variable name
write(paste0(var.name, " <- 6"), "tmp.R")
#source that script file
source("tmp.R")
#remove the script file for tidiness
file.remove("tmp.R")

xбудет изменено на 6, и если имя переменной было любым, кроме "x", эта переменная аналогичным образом будет изменена на 6.


2

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

varnames = c('jan', 'feb', 'march')
file_names = list_files('path to multiple csv files saved on drive')
assign(varnames[1], read.csv(file_names[1]) # This will assign the variable

Оттуда, если вы попытаетесь распечатать переменную varnames[1], она вернет jan. Чтобы обойти это, вам нужно сделать print(get(varnames[1]))


1

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

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

original_string <- "variable_name=\"10\"" # Your original instruction, but with an actual numeric on the right, stored as character.
library(magrittr) # Or library(tidyverse), but it seems a bit overkilled if the point is just to import pipe-stream operator
eval(parse(text=paste(eval(original_string), "%>% as.numeric")))
print(variable_name)
#[1] 10

В принципе, то , что мы делаем, что мы «улучшить» вашу инструкцию variable_name="10"так , что она становится variable_name="10" %>% as.numeric, что является эквивалентом variable_name=as.numeric("10")с magrittrсинтаксисом трубы потока. Затем мы оцениваем это выражение в текущей среде.

Надеюсь, это поможет тому, кто будет бродить здесь 8 лет спустя ;-)


0

Если вы хотите преобразовать строку в переменную внутри тела функции, но хотите иметь глобальную переменную:

test <- function() {
do.call("<<-",list("vartest","xxx"))
}
test()
vartest

[1] "xxx"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.