Đây là đường dẫn đọc và xử lý nó. Giả sử dữ liệu nằm trong L
theo Ghi chú ở cuối. Bạn có thể sẽ cần phải tạo điều này với một cái gì đó như L <- readLines("myfile.dat")
.
Cắt khoảng trắng đầu và cuối bằng cách sử dụng trimws
- bước này có thể không cần thiết nhưng không thể làm tổn hại chỉ trong trường hợp dữ liệu không có khoảng trắng ở đầu dòng. Sau đó, grep
ra dòng bắt đầu bằng một chữ số hoặc chứa var
thay thế mỗi số v
, a
, r
, =
bằng dấu cách và thay thế bằng dấu phẩy bằng dòng mới. Điều đó đặt nó ở dạng read.table
có thể đọc nó vào một khung dữ liệu 2 cột trong đó cột đầu tiên là 1, 2, 3 theo sau là số lặp và cột thứ hai là giá trị của var1
, var2
, var3
và data
tất cả lặp lại cho mỗi nhóm. Chúng tôi tạo một biến nhóm bằng cách xác định các lần chạy tuần tự bằng cách sử dụng biểu thức cumsum(...) %/% 2
. Điều này giả định rằng có ít nhất 2 lần lặp (0 và 1) cho mỗi nhóm. (Từ dữ liệu được hiển thị, nó sẽ cho biết rằng đây là trường hợp nhưng nếu không nó có thể được giải quyết bằng mã bổ sung như sau.) Cuối cùng, chia cho biểu thức nhóm và làm lại mỗi nhóm tách ra thành khung dữ liệu cần thiết.
library(purrr)
L %>%
trimws %>%
grep(pattern = "^\\d|var", value = TRUE) %>%
chartr(old = "var=,", new = " \n") %>%
read.table(text = .) %>%
split(cumsum(c(FALSE, diff(.$V1) != 1)) %/% 2) %>%
map_df(function(x) data.frame(var1 = x[1, 2], var2 = x[2, 2],
var3 = x[3, 2],iteration = x[-(1:3), 1], data = x[-(1:3), 2]))
cho:
var1 var2 var3 iteration data
1 0 -5 1.8 0 1.203
2 0 -5 1.8 1 1.206
3 0 -5 1.8 2 2.206
4 0 -5 1.8 3 1.201
5 0 -5 1.8 4 1.204
6 0 -5 1.8 5 1.204
7 0 -5 1.8 6 1.204
8 10 -5 1.8 0 1.203
9 10 -5 1.8 1 1.206
10 10 -5 1.8 2 2.206
11 10 -5 1.8 3 1.201
biến Này biến thể của mã cũng xử lý các trường hợp chỉ có một lần lặp, tức là lặp 0, và đơn giản hóa việc tính toán nhóm tại các chi phí của một vài nhiều dòng mã hơn. Ở đây hai trường hợp -9999 có thể là bất kỳ số nào không xuất hiện trong dữ liệu.
L %>%
grep(pattern = "^\\s*\\d|var", value = TRUE) %>%
sub(pattern = "var", replacement = "-9999 var") %>%
gsub(pattern = "[^0-9.,-]", replacement = " ") %>%
gsub(pattern = ",", replacement = "\n") %>%
strsplit("\\s+") %>%
unlist %>%
as.numeric %>%
split(cumsum(. == -9999)) %>%
map_df(function(x) {
x <- t(matrix(x[-1], 2))
data.frame(var1 = x[1, 2], var2 = x[2, 2], var3 = x[3, 2],
iteration = x[-(1:3), 1], data = x[-(1:3), 2])
})
dplyr/tidyr Chúng tôi luân phiên có thể sử dụng dplyr và tidyr gói.vars
có 3 cột var1
, var2
và var3
và một hàng cho mỗi nhóm. values
có một cột chứa khung dữ liệu hai cột lồng nhau của dữ liệu lặp và dữ liệu và có một hàng cho mỗi nhóm nhưng mỗi hàng như vậy chứa một khung dữ liệu của nhiều hàng.
library(tidyr)
library(dplyr)
vars <- L %>%
grep(pattern = "var", value = TRUE) %>%
gsub(pattern = "[=,]", replacement = " ") %>%
read.table(text = ., col.names = c(NA, "var1", NA, "var2", NA, "var3")) %>%
select(var1, var2, var3)
values <- L %>%
trimws %>%
grep(pattern = "^\\d", value = TRUE) %>%
read.table(text = ., col.names = c("iteration", "data")) %>%
mutate(g = cumsum(iteration == 0)) %>%
nest(-g) %>%
select(-g)
cbind(vars, values) %>% unnest
Lưu ý:
Lines <- "Measurement: mc
Loop:
var1=0, var2=-5, var3=1.8
values:
iteration data
0 1.203
1 1.206
2 2.206
3 1.201
4 1.204
5 1.204
6 1.204
statistics:
max 1.206
min 1.201
mean 1.204
stddev 0.001
avgdev 0.001
failedtimes 0
Measurement: mc
Loop:
var1=10, var2=-5, var3=1.8
values:
iteration data
0 1.203
1 1.206
2 2.206
3 1.201
statistics:
max 1.206
min 1.201
mean 1.204
stddev 0.001
avgdev 0.001
failedtimes 0"
L <- readLines(textConnection(Lines))
Các bạn đã thử sử dụng ' 'skip' read.table' và' đối số nrows' để nắm bắt 'iteration' và' dữ liệu' cột? – adatum
Ồ, và nếu đó là tệp có định dạng rộng cố định, có 'read.fwf' cho điều đó. – adatum