2012-11-05 107 views
44

Tôi có một danh sách có chiều dài 130.000, trong đó mỗi phần tử là một vectơ ký tự có độ dài 110. Tôi muốn chuyển đổi danh sách này thành ma trận có kích thước 1,430,000 * 10. Làm thế nào tôi có thể làm điều đó hiệu quả hơn? Mã của tôi là:Làm thế nào để chuyển đổi danh sách thành ma trận hiệu quả hơn trong R?

output=NULL 
for(i in 1:length(z)) output=rbind(output,matrix(z[[i]],ncol=10,byrow=T)) 
+2

Nếu bạn muốn kích thước là 1.430.000 * 11 tại sao bạn đặt ncol là 10? – Dason

+1

Chờ- khi bạn nói rằng mỗi mục có 11 ký tự, bạn có nghĩa là nó là một vectơ với 11 mục? Ban đầu tôi nghĩ rằng mỗi một chuỗi với 11 ký tự trong đó. Bạn có thể hiển thị 'z [1: 2]' làm ví dụ không? –

+0

Cảm ơn Dason và David! Đó là một lỗi đánh máy. Tôi đã sửa chữa nó. – user1787675

Trả lời

99

này cần được tương đương với mã hiện tại của bạn, chỉ nhanh hơn rất nhiều:

output <- matrix(unlist(z), ncol = 10, byrow = TRUE) 
+4

Bingo. Điều này cũng nhanh hơn nhiều so với giải pháp của tôi, nhưng tôi không thể nghĩ nó đủ nhanh. –

+9

+1, nhưng tôi khuyên bạn nên đặt 'USE.NAMES = FALSE' trong' unlist' để tiết kiệm thời gian và bộ nhớ. –

+1

Nó phải là 'use.names' (tức là chữ thường). –

5

Nó sẽ giúp có thông tin mẫu về đầu ra của bạn. Sử dụng đệ quy rbind trên những thứ lớn hơn và lớn hơn là không được đề xuất. Tôi đoán đầu tiên tại một cái gì đó mà có thể giúp bạn:

z <- list(1:3,4:6,7:9) 
do.call(rbind,z) 

Xem a related question cho hiệu quả cao hơn, nếu cần thiết.

11

tôi nghĩ bạn muốn

output <- do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE)) 

tức là kết hợp sử dụng @do.call(rbind,...) BlueMagister với một tuyên bố lapply để chuyển đổi các yếu tố danh sách cá nhân vào 11 * 10 ma trận ...

Benchmarks (hiển thị @ giải pháp unlist của flodel nhanh hơn so với tôi và nhanh hơn 230 lần so với phương pháp ban đầu ...)

n <- 1000 
z <- replicate(n,matrix(1:110,ncol=10,byrow=TRUE),simplify=FALSE) 
library(rbenchmark) 
origfn <- function(z) { 
    output <- NULL 
    for(i in 1:length(z)) 
     output<- rbind(output,matrix(z[[i]],ncol=10,byrow=TRUE)) 
} 
rbindfn <- function(z) do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE)) 
unlistfn <- function(z) matrix(unlist(z), ncol = 10, byrow = TRUE) 

##   test replications elapsed relative user.self sys.self 
## 1 origfn(z)   100 36.467 230.804 34.834 1.540 
## 2 rbindfn(z)   100 0.713 4.513  0.708 0.012 
## 3 unlistfn(z)   100 0.158 1.000  0.144 0.008 

Nếu tỷ lệ này phù hợp (tức là bạn không gặp vấn đề về bộ nhớ), vấn đề đầy đủ sẽ mất khoảng 130 * 0,2 giây = 26 giây trên một máy tính có thể so sánh được (tôi đã làm điều này trên MacBook Pro 2 tuổi).

+0

Thật là kỳ diệu! Mất khoảng 20 giây để làm điều này trên máy toshiba một tuổi của tôi, điều này giúp tôi tiết kiệm rất nhiều thời gian. Và chức năng của bạn để cho thấy thời gian chạy cũng rất thú vị. – user1787675

-2

bạn có thể sử dụng as.matrix như sau:

output <- as.matrix(z) 
Các vấn đề liên quan