2014-12-03 15 views
7

Có cách nào để thực hiện foreach() trả về một danh sách có tên/data.frame hay không. Ví dụ.foreach: Giữ tên

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo) %do% { x * 2 } 

trả về list(2, 4). Tôi muốn nó trả lại list(a = 2, b = 4).

Ngoài ra, có cách nào để truy cập tên từ bên trong vòng lặp không?

(Tôi không quan tâm đến một giải pháp mà gán tên sau khi vòng lặp foreach.)

Trân

+2

Không chắc chắn nếu 'foreach' có chức năng cho việc này. Tuy nhiên bạn có thể thay đổi vòng lặp của bạn thành 'foreach (i = seq_along (foo)) {x <- foo [[i]]; ...} 'sẽ cho phép bạn truy cập tên của từng phần tử bằng' tên (foo) [i] ' – konvas

+0

Bạn cũng có thể sử dụng' x = Bản đồ (cấu trúc, .Data = lapply (foo, list), names = tên (foo)) 'để lấy các tên bên trong vòng lặp, như thể vòng lặp đang sử dụng' ['thay vì' [['để truy cập các phần tử của' foo'. –

Trả lời

9

Tôi đã sử dụng giải pháp của bạn cho đến khi tôi cần thiết để sử dụng một foreach lồng nhau (với các nhà điều hành %:%). Tôi đến với điều này:

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo, .final = function(x) setNames(x, names(foo))) %do% { 
    x * 2 
    } 

Bí quyết là sử dụng .final luận (mà là một chức năng áp dụng một lần tại kết quả cuối cùng) để thiết lập các tên. Điều này là đẹp hơn bởi vì nó không sử dụng một biến tạm thời và tổng thể sạch hơn. Nó hoạt động với các danh sách lồng nhau để bạn có thể bảo toàn các tên trên nhiều lớp của cấu trúc.

Lưu ý rằng điều này chỉ hoạt động chính xác nếu foreach có đối số .inorder=T (là mặc định).

3

Cám ơn các khuyến nghị của bạn. Đây là những gì tôi đã đưa ra:

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo, n = names(foo), .combine = c) %do% { 
    rv <- list() 
    rv[[n]] <- x * 2 
    rv 
}