Tạo một danh sách tên biến trong một vòng lặp for, sau đó gán giá trị cho chúng


27

Tôi tự hỏi nếu có một cách đơn giản để tạo danh sách các biến bằng vòng lặp for và đưa ra giá trị của nó.

for(i in 1:3)
{
  noquote(paste("a",i,sep=""))=i
}

Trong đoạn mã trên, tôi cố gắng tạo a1, a2, a3, mà gán cho giá trị của 1, 2, 3. Tuy nhiên, R đưa ra một thông báo lỗi. Cảm ơn bạn đã giúp đỡ.


3
Tôi nghi ngờ bạn phải làm điều này - có vẻ như bạn đang làm một cái gì đó rất sai.

@mbq, trong Eviews cho ví dụ này là khá bình thường mã hóa thực tế. Không phải là tôi ủng hộ nó, Eview chỉ đánh giá thấp hơn một chút so với Excel trong danh sách phần mềm độc ác hàng đầu của tôi :)
mpiktas

6
@mpiktas Trong R, việc lập danh sách, đặt namestham số của nó là tự nhiên hơn và sau đó chỉ cần sử dụng nó, attachchuyển đổi nó thành một môi trường có list2envevalbên trong nó. Không có vòng lặp, phân tích cú pháp hoặc những thứ xấu xí khác.

@mbq, hm, list2envlà một chức năng tương đối mới. Và nó vẫn sẽ tạo ra các biến trong môi trường nào đó, khi OP muốn lấy các biến trong môi trường hàng đầu. Vì vậy, sự xấu xí vẫn còn đó :)
mpiktas

2
Đối với các câu hỏi trong tương lai có tính chất tương tự, tôi đề nghị loại câu hỏi này thực sự thuộc về StackOverflow. Câu hỏi không có gì để làm với số liệu thống kê mỗi se.
Sao Hỏa

Câu trả lời:


41

Bạn đang tìm kiếm assign().

for(i in 1:3){
  assign(paste("a", i, sep = ""), i)    
}

cho

> ls()
[1] "a1"          "a2"          "a3" 

> a1
[1] 1
> a2
[1] 2
> a3
[1] 3

Cập nhật

Tôi đồng ý rằng việc sử dụng các vòng lặp là (rất thường xuyên) kiểu mã hóa R xấu (xem thảo luận ở trên). Sử dụng list2env()(cảm ơn @mbq vì đã đề cập đến nó), đây là một giải pháp khác cho câu hỏi của @Han Lin Shang:

x <- as.list(rnorm(10000))
names(x) <- paste("a", 1:length(x), sep = "")
list2env(x , envir = .GlobalEnv)

21

Nếu các giá trị nằm trong vector, vòng lặp là không cần thiết:

vals <- rnorm(3)
n    <- length(vals)
lhs  <- paste("a",    1:n,     sep="")
rhs  <- paste("vals[",1:n,"]", sep="")
eq   <- paste(paste(lhs, rhs, sep="<-"), collapse=";")
eval(parse(text=eq))

Như một lưu ý phụ, đây là lý do tại sao tôi yêu R.


4
library(fortunes) fortune(106)
Roman Luštrik

@Roman, lạ, tôi đã bắt đầu sử dụng parsesau khi đọc các trang trợ giúp R. Tôi đồng ý rằng đôi khi nó là một việc quá mức, ví dụ như trong formulaquản lý, nhưng tôi thấy nó rất hữu ích. Lưu ý rằng tôi không thể suy nghĩ lại câu hỏi như được đề xuất trong tài sản, vì tôi đã không hỏi nó.
mpiktas

1
@mpiktas: nó phải liên quan đến thực tế là các quy tắc phạm vi cơ bản có thể dẫn đến kết quả không thể đoán trước khi được sử dụng trong một hàm. Ngoài ra (như đã đề cập trong các tệp trợ giúp), R và S có thể cho một kết quả khác do sự khác biệt trong quy tắc phạm vi. Nó cũng chậm hơn các giải pháp khác. Điều này sẽ quan trọng khi bạn phải làm điều này nhiều lần. Và cuối cùng nhưng không kém phần quan trọng, trong hầu hết các trường hợp, có một giải pháp thanh lịch và dễ dàng hơn là sử dụng eval (parse ()). Trong trường hợp này, đó là làm việc với danh sách hoặc sử dụng gán.
Joris Meys

1
@mpiktas: Tôi chưa bao giờ nói nó thiếu. Tôi chỉ cho bạn lý do tại sao nói chung, một cấu trúc eval (parse ()) được khuyên dùng bởi ví dụ Thomas Lumley, thành viên của nhóm phát triển lõi R. (cfr giới thiệu của @Roman Lustrik)
Joris Meys

1
chính xác, thực tế xấu như sử dụng gán để tạo nhiều biến phần tử đơn lẻ nên được khuyến khích
mdsumner
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.