2010-11-05 37 views
39

Tôi có một tệp trong đó mỗi dòng là tập hợp các kết quả được thu thập trong bản sao cụ thể của thử nghiệm. Số lượng kết quả trong mỗi thử nghiệm (nghĩa là số cột trong mỗi hàng) có thể khác nhau. Cũng không có tầm quan trọng đối với thứ tự kết quả trong mỗi hàng (kết quả đầu tiên trong hàng 1 và kết quả đầu tiên 2 không liên quan nhiều hơn bất kỳ cặp nào khác; đây là đặt kết quả).Cách tốt nhất để đọc từng dòng trong R là gì?

Các tập tin trông giống như sau:

2141 0 5328 5180 357 5335 1 5453 5325 5226 7 4880 5486 0 
2650 0 5280 4980 5243 5301 4244 5106 5228 5068 5448 3915 4971 5585 4818 4388 5497 4914 5364 4849 4820 4370 
2069 2595 2478 4941 
2627 3319 5192 5106 32 4666 3999 5503 5085 4855 4135 4383 4770 
2005 2117 2803 2722 2281 2248 2580 2697 2897 4417 4094 4722 5138 5004 4551 5758 5468 17361 
1914 1977 2414 100 2711 2171 3041 5561 4870 4281 4691 4461 5298 3849 5166 5578 5520 4634 4836 4905 5105 5089 
2539 2326 0 4617 3735 0 5122 5439 5238 1 
25 5316 21173 4492 5038 5944 5576 5424 5139 5184 5 5096 4963 2771 2808 2592 2 
4963 9428 17152 5467 5202 6038 5094 5221 5469 5079 3753 5080 5141 4097 5173 11338 4693 5273 5283 5110 4503 51 
2024 2 2822 5097 5239 5296 4561 

trừ mỗi dòng là dài hơn nhiều (lên đến vài nghìn giá trị). Như có thể thấy, tất cả các giá trị là số nguyên không âm.

Để đặt ngắn gọn - đây không phải là bảng bình thường, nơi các cột có ý nghĩa. Nó chỉ là một loạt các kết quả - mỗi bộ trong một dòng.

Tôi muốn đọc tất cả kết quả, sau đó thực hiện một số thao tác trên mỗi thử nghiệm (hàng), chẳng hạn như tính toán ecdf. Tôi cũng muốn tính toán ecdf trung bình trên tất cả các bản sao.

Vấn đề của tôi - tôi nên đọc tệp tìm kiếm kỳ lạ này như thế nào? Tôi rất sử dụng để read.table mà tôi không chắc mình có bao giờ thử bất cứ điều gì khác ... Tôi có phải sử dụng một số mức thấp như readlines không? Tôi đoán đầu ra ưa thích sẽ là một danh sách (hoặc vectơ?) Của vectơ. Tôi nhìn vào scan nhưng có vẻ như tất cả các vectơ phải có cùng độ dài ở đó.

Mọi đề xuất sẽ được đánh giá cao.

CẬP NHẬT Tiếp theo gợi ý dưới đây, bây giờ tôi làm điều gì đó như thế này:

con <- file('myfile') 
open(con); 
results.list <- list(); 
current.line <- 1 
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) { 
results.list[[current.line]] <- as.integer(unlist(strsplit(line, split=" "))) 
current.line <- current.line + 1 
} 
close(con) 

vẻ để làm việc. Nó có ổn không?

Khi tôi summary(results.list) tôi nhận được: Chiều dài lớp Chế độ

 Length Class Mode 
[1,] 1091 -none- numeric 
[2,] 1070 -none- numeric 
    .... 

nên không phải là lớp có số nguyên? Và chế độ là gì?

+0

Loại tệp nào? Bạn có thể hiển thị một ví dụ? –

+0

@Brandon Bertelsen: chắc chắn, hãy xem bài đăng cập nhật. –

Trả lời

27

Ví dụ Josh liên kết là một trong những tôi luôn luôn sử dụng.

inputFile <- "/home/jal/myFile.txt" 
con <- file(inputFile, open = "r") 

dataList <- list() 
ecdfList <- list() 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    myVector <- (strsplit(oneLine, " ")) 
    myVector <- list(as.numeric(myVector[[1]])) 
    dataList <- c(dataList,myVector) 

    myEcdf <- ecdf(myVector[[1]]) 
    ecdfList <- c(ecdfList,myEcdf) 

    } 

close(con) 

Tôi đã chỉnh sửa ví dụ để tạo hai danh sách từ dữ liệu ví dụ của bạn. dataList là danh sách trong đó mỗi mục trong danh sách là một vectơ các giá trị số từ mỗi dòng trong tệp văn bản của bạn. ecdfList là danh sách trong đó mỗi phần tử là một ecdf cho mỗi dòng trong tệp văn bản của bạn.

Có lẽ bạn nên thêm một số hàm try() hoặc trycatch() vào đó để xử lý đúng các tình huống mà không thể tạo ecdf vì số không hoặc một số thứ như vậy. Nhưng ví dụ trên sẽ khiến bạn khá gần gũi. Chúc may mắn!

+0

+ 1thanks! để chuyển đổi dòng vào một vectơ các số nguyên tôi sử dụng 'as.integer (unlist (strsplit (oneLine, split =" ")))'. Nó hoạt động, nhưng tôi tự hỏi nếu có một cách tốt hơn? Ngoài ra, làm thế nào bạn sẽ đề nghị đặt tất cả những vectơ trong một signle một danh sách/vector? Cũng lưu ý tôi đã thêm một mẫu vào OP. –

+0

Tôi thực sự không chắc chắn liệu chuyển đổi của bạn có "tốt hơn" hay không. Phương pháp tôi sử dụng là phương pháp mà tôi sử dụng khi học R và tôi có thói quen xấu khi học một thành ngữ duy nhất hoạt động và sau đó luôn sử dụng thành ngữ đó ngay cả khi có "cách tốt hơn". –

17

Có, bạn có thể sử dụng readLines. JD Long has a good example, mà tôi đã chỉnh sửa một chút và được cung cấp bên dưới.

con <- file(inputFile, open = "r") 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    # do stuff 
} 

close(con) 
+2

Tuyệt. Tôi đã chơi đùa một lúc với điều kiện 'while'. Lạ lùng là chúng ta không có 'isEOF()' hay như vậy. –

2

Sử dụng

line <- readLines(con, 1) 

để đọc một dòng từ kết nối con, có thể đơn giản như con <- file(filename, "r").

5

Hoặc:

df <- read.delim(file="whatever", header=F, sep = " ") 
1

nếu bạn biết rằng các giá trị trong các tập tin là các số nguyên, bạn có thể sử dụng scan() thay vì readLines(), nhưng cũng trong một vòng lặp:

open(con) 
results.list <- list(); 
current.line <- 1 
while(length(line <- scan(con,what=integer(0),nlines=1,quiet=TRUE))>0) { 
    results.list[[current.line]] <- line 
    current.line <- current.line + 1 
} 
close(con) 

Bạn sẽ nhận được một danh sách các vectơ số.

8

Tại sao phải quan tâm đến việc đọc từng dòng?

results.list <- lapply(strsplit(readLines("myfile")," "), as.integer) 

cung cấp cho bạn danh sách các vectơ nguyên.

Giới thiệu về câu hỏi bổ sung của bạn: xem ?mode (viết tắt là mode là số cho số, typeof có thể là số nguyên hoặc gấp đôi và class số hoặc số nguyên). Để xem liệu có số nguyên nào không, hãy kiểm tra str(results.list) hoặc lapply(results.list, class).

Các vấn đề liên quan