แปลงสตริงเป็นชื่อตัวแปร


103

ฉันใช้ R เพื่อแยกวิเคราะห์รายการสตริงในรูปแบบ:

original_string <- "variable_name=variable_value"

ขั้นแรกฉันแยกชื่อตัวแปรและค่าจากสตริงเดิมและแปลงค่าเป็นคลาสตัวเลข

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

จากนั้นฉันต้องการกำหนดค่าให้กับตัวแปรที่มีชื่อเดียวกับสตริง parameter_name

variable_name <- parameter_value

ฟังก์ชันนี้คืออะไร / คืออะไร?

คำตอบ:


128

มอบหมายคือสิ่งที่คุณกำลังมองหา

assign("x", 5)

x
[1] 5

แต่ผู้ซื้อระวัง

ดูคำถามที่พบบ่อย R 7.21 http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f


1
“ ผู้ซื้อระวัง” เป็นวิธีที่ค่อนข้างน่าตำหนิในการบอกว่าคุณแทบไม่ควรทำเช่นนี้เพราะแทบจะไม่ใช่วิธีแก้ปัญหาที่ดีเลย
Konrad Rudolph

ก่อนที่จะใช้วิธีนี้คุณอาจพิจารณาสร้างรายการและการเพิ่มมูลค่าparameter_list <- list() paramter_list[parameter_name] <- parameter_value
ณัฐ



20

ใช้x=as.name("string") คุณสามารถใช้แล้วใช้xเพื่ออ้างถึงตัวแปรด้วยสตริงชื่อ

ฉันไม่รู้ว่ามันตอบคำถามของคุณถูกต้องหรือไม่


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

18

ฟังก์ชั่นที่คุณกำลังมองหาคือget():

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

การยืนยันว่าที่อยู่หน่วยความจำเหมือนกัน:

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

Reference: R FAQ 7.21 ฉันจะเปลี่ยนสตริงให้เป็นตัวแปรได้อย่างไร?


1
เยี่ยมมาก! นี่เป็นคำตอบที่กระชับที่สุดที่ฉันพบ มีวิธีการย้อนกลับที่กระชับในทำนองเดียวกันหรือไม่? เช่นเดียวกับx <- 42; deparse(substitute(x))
Miao Cai

10

strsplitเพื่อแยกวิเคราะห์อินพุตของคุณและตามที่ Greg กล่าวถึง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 เพื่อเขียนโค้ดเพื่อดำเนินการเอง

สมมติว่าฉันเพิ่งกำหนดค่า 5 ให้กับx( var.name <- "x"; assign(var.name, 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

หากคุณต้องการแปลงสตริงเป็นตัวแปรภายใน body of function แต่คุณต้องการมีตัวแปร global:

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

[1] "xxx"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.