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


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.