Chuyển đổi chuỗi thành một tên biến


100

Tôi đang sử dụng R để phân tích cú pháp một danh sách các chuỗi có dạng:

original_string <- "variable_name=variable_value"

Đầu tiên, tôi trích xuất tên biến và giá trị từ chuỗi ban đầu và chuyển đổi giá trị thành lớp số.

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

Sau đó, tôi muốn gán giá trị cho một biến có cùng tên với chuỗi tên_biến.

variable_name <- parameter_value

(Các) chức năng để làm việc này là gì?

Câu trả lời:


122

chỉ định là những gì bạn đang tìm kiếm.

assign("x", 5)

x
[1] 5

nhưng người mua hãy cẩn thận.

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


“Hãy cẩn thận với người mua” là một cách nói khá phiến diện rằng bạn gần như không bao giờ nên làm điều này, bởi vì nó hầu như không bao giờ là một giải pháp tốt cho một vấn đề nhất định.
Konrad Rudolph

66

Bạn có thể sử dụng do.call:

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

10
+1 cho suy nghĩ. Mọi người (bao gồm cả tôi) thường quên rằng <-bản thân nó là một chức năng.
Rob


19

sử dụng x=as.name("string") bạn có thể sử dụng sau đó sử dụng xđể tham chiếu đến biến có chuỗi tên.

Tôi không biết nếu nó trả lời đúng câu hỏi của bạn


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

18

Chức năng bạn đang tìm kiếm là get():

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

Xác nhận rằng địa chỉ bộ nhớ là giống hệt nhau:

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

Tham khảo: R FAQ 7.21 Làm cách nào để biến một chuỗi thành một biến?


1
Tuyệt quá! Đây là câu trả lời ngắn gọn nhất mà tôi tìm thấy. Có cách nào ngắn gọn tương tự để làm ngược lại không? giống nhưx <- 42; deparse(substitute(x))
Miao Cai

10

strsplitđể phân tích cú pháp đầu vào của bạn và, như Greg đã đề cập, assignđể gán các biến.

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

assignlà tốt, nhưng tôi không tìm thấy một hàm để tham chiếu trở lại biến mà bạn đã tạo trong một tập lệnh tự động. (as.name dường như hoạt động theo cách ngược lại). Những lập trình viên có kinh nghiệm hơn chắc chắn sẽ có một giải pháp tốt hơn, nhưng giải pháp này hoạt động và có lẽ hơi hài hước, ở chỗ nó yêu cầu R viết mã cho chính nó để thực thi.

Giả sử tôi vừa gán giá trị 5 cho x( var.name <- "x"; assign(var.name, 5)) và tôi muốn thay đổi giá trị thành 6. Nếu tôi đang viết tập lệnh và không biết trước tên biến ( var.name) sẽ là gì (dường như là điểm của assignchức năng), tôi không thể chỉ đơn giản là x <- 6var.namecó thể đã được "y". Vì vậy tôi làm:

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

xsẽ được thay đổi thành 6 và nếu tên biến không phải là bất kỳ điều gì khác "x", biến đó tương tự sẽ được đổi thành 6.


2

Tôi đã làm việc với điều này một vài ngày trước và nhận thấy rằng đôi khi bạn sẽ cần sử dụng get()hàm để in kết quả của biến của bạn. I E :

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

Từ đó, nếu bạn cố gắng in biến varnames[1], nó sẽ trả về 'jan'. Để giải quyết vấn đề này, bạn cần phải làm print(get(varnames[1]))


1

Có lẽ tôi không hiểu vấn đề của bạn đúng, vì ví dụ của bạn đơn giản. Theo sự hiểu biết của tôi, bạn có một loạt các hướng dẫn được lưu trữ trong các vectơ ký tự và những hướng dẫn đó rất gần với việc được định dạng đúng, ngoại trừ việc bạn muốn chuyển thành viên phù hợp thành số.

Nếu sự hiểu biết của tôi là đúng, tôi muốn đề xuất một cách tiếp cận hơi khác, không dựa vào việc tách chuỗi ban đầu của bạn, mà trực tiếp đánh giá hướng dẫn của bạn (với một chút cải thiện).

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

Về cơ bản, những gì chúng tôi đang làm là chúng tôi 'cải thiện' hướng dẫn của bạn variable_name="10"để nó trở thành variable_name="10" %>% as.numeric, tương đương variable_name=as.numeric("10")với magrittrcú pháp pipe-stream. Sau đó, chúng tôi đánh giá biểu thức này trong môi trường hiện tại.

Hy vọng điều đó sẽ giúp một người nào đó sẽ lang thang ở đây 8 năm sau ;-)


0

Nếu bạn muốn chuyển đổi chuỗi thành biến bên trong nội dung của hàm, nhưng bạn muốn có biến toàn cục:

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

[1] "xxx"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.