Konwertuj ciąg na nazwę zmiennej


100

Używam języka R do analizowania listy ciągów w postaci:

original_string <- "variable_name=variable_value"

Najpierw wyodrębniam nazwę zmiennej i wartość z oryginalnego ciągu i konwertuję wartość na klasę numeryczną.

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

Następnie chciałbym przypisać wartość zmiennej o takiej samej nazwie, jak łańcuch nazwa_parametru.

variable_name <- parameter_value

Jakie są funkcje w tym celu?

Odpowiedzi:



66

Możesz użyć do.call:

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

10
+1 za myślenie. Ludzie (łącznie ze mną) zwykle zapominają, że <-jest to funkcja sama w sobie.
Rob


20

użyj x=as.name("string") możesz użyć, a następnie użyj, xaby odwołać się do zmiennej o nazwie łańcuchowej.

Nie wiem, czy poprawnie odpowiada na twoje pytanie


2
x=as.symbol("string")
Enrique Pérez Herrero

18

Funkcja, której szukasz, to get():

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

Potwierdzenie, że adres pamięci jest identyczny:

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

Odniesienie: R FAQ 7.21 Jak zamienić ciąg znaków w zmienną?


1
Wspaniały! To najbardziej zwięzła odpowiedź, jaką znalazłem. Czy istnieje podobnie zwięzły sposób na odwrócenie tego? tak jakx <- 42; deparse(substitute(x))
Miao Cai,

10

strsplitaby przeanalizować dane wejściowe i, jak wspomniał Greg, assignprzypisać zmienne.

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

assignjest dobry, ale nie znalazłem funkcji odwołującej się do zmiennej, którą utworzyłeś w automatycznym skrypcie. ( as.namewydaje się działać w drugą stronę). Bardziej doświadczeni programiści bez wątpienia będą mieli lepsze rozwiązanie, ale to rozwiązanie działa i być może jest nieco zabawne, ponieważ zmusza R do napisania kodu do wykonania.

Powiedzmy, że właśnie przypisałem wartość 5 do x( var.name <- "x"; assign(var.name, 5)) i chcę zmienić wartość na 6. Jeśli piszę skrypt i nie wiem z góry, jaka będzie nazwa zmiennej ( var.name) (co wydaje się być celem assignfunkcja), nie mogę po prostu podać, x <- 6ponieważ var.namemogło tak być "y". Ja również:

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")

xzostanie zmieniona na 6, a jeśli nazwa zmiennej była inna niż "x", ta zmienna podobnie zostanie zmieniona na 6.


2

Pracowałem nad tym kilka dni temu i zauważyłem, że czasami będziesz musiał użyć get()funkcji, aby wydrukować wyniki swojej zmiennej. tj .:

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

Stamtąd, jeśli spróbujesz wydrukować zmienną varnames[1], zwraca ona „jan”. Aby obejść ten problem, musisz zrobić print(get(varnames[1]))


1

Może nie zrozumiałem twojego problemu dobrze, z powodu prostoty twojego przykładu. Według mojego rozumienia, masz serię instrukcji przechowywanych w wektorach znakowych, a instrukcje te są bardzo bliskie poprawnego sformatowania, z wyjątkiem tego, że chciałbyś rzutować właściwy element na numeryczny.

Jeśli dobrze rozumiem, chciałbym zaproponować nieco inne podejście, które nie polega na dzieleniu oryginalnego ciągu, ale bezpośrednio ocenia twoją instrukcję (z niewielką poprawą).

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

Zasadniczo to, co robimy, polega na tym, że „poprawiamy” Twoje instrukcje, variable_name="10"tak aby stały się variable_name="10" %>% as.numeric, co jest odpowiednikiem variable_name=as.numeric("10")zmagrittr składnią rura strumienia. Następnie oceniamy to wyrażenie w obecnym środowisku.

Mam nadzieję, że pomoże to komuś, kto wędrowałby tu 8 lat później ;-)


0

Jeśli chcesz przekonwertować ciąg znaków na zmienną w treści funkcji, ale chcesz mieć zmienną globalną:

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

[1] "xxx"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.