2013-06-20 17 views
0

Это вопрос, который основан на вопросе, который я задал раньше: Read many files, compute something, save results in dataframe (R).R: проблемы, связанные с построением вложенных циклов и результатов сбережений

Тем не менее у меня есть около 100 файлов с данными моделирования. Тема - это деградация двух веществ, поэтому у меня есть 3 соответствующие колонки: время (в минутах), относительная концентрация вещества 1 (суб1, от 1,0 до нуля) и относительная концентрация. вещества 2 (Sub2).

Это прекрасно работает, чтобы определить определенные уровни деградации, которые я должен ввести вручную:

z <- 0.25 #Abbaugrad 
a <- 1-z 

setwd("H:/...") 
names<-dir(pattern="Data.txt") 
result <- data.frame(matchs1 = numeric(length(names)) , matchs2 = numeric(length(names))) 
for (i in 1:length(names)){ 
    data <- read.table(file=names[i],header=T) 
    matchs1 <- with(data, Time[abs(Sub1-a)==min(abs(Sub1-a))]) 
    matchs2 <- with(data , Time[abs(Sub2-a)==min(abs(Sub2-a))]) 
    result[i,] <- cbind(matchs1,matchs2) 
    } 

Теперь я хотел бы автоматизировать этот процесс, поэтому я не придется вводить уровни деградации, но результаты вычисляются вложенный цикл for.

Сначала я подумал, что для будущих идей может быть лучше работать с datalist, e. г. для построения некоторых данных из этих файлов, так что я сделал:

filelist <- list.files(pattern = "Data.txt") 
datalist <- lapply(filelist, function(xx)read.table(xx,header=T)) 

Это работало отлично, чтобы построить некоторые прогоны моделирования.

plot(datalist[[1]][,3], type="l",col="red") 
for (i in 1:10){ 
    lines(datalist[[i]][,3],col="red") 
    } 

Причина пытается построить следующий цикл, что я хочу, чтобы выяснить, среднее выбежать из 100. Я думаю, что я должен узнать время, когда 1% до 100% разлагаются для каждого а затем вычислить среднее значение для каждого уровня.

Теперь моя простая попытка только для одного вещества:

test <- data.frame(matrix(ncol=99, nrow = 100)) #100 runs, 99 levels 
for (i in 1:length(datalist)){ 
    for (j in seq(0.01,0.99,by=0.01)){ 
    matchs1 <- with(datalist[[i]], Time[abs(Sub1-j)==min(abs(Sub1-j))]) 
    level <- paste('l',j,sep="") 
    test[j,] <- cbind(matchs1,level) 
    }} 

Я хотел построить новый dataframe где результат для каждого уровня (от 0,01 до 1) сохраняется в одном столбце. Тогда я мог бы вычислить среднее значение для каждой колонии. Но я уже не могу вычислить фрейм данных.

Возможно, есть и более простой способ получить среднее значение различных временных рядов.

Я бы очень признателен за любую помощь.

Редактировать: Мне сложно предоставить образцы данных, потому что у меня есть 100 файлов. В каждом из них есть три соответствующих столбца: Time, Sub1, Sub2. Вы можете представить себе это так:

Time Sub1 Sub2 
0  1.0000 1.0000 
60  0.9511 0.9888 
120  0.9022 0.9555 
... 
24000 0.0101 0.0891 

Я хочу, чтобы вычислить средний пробег, поэтому для каждого из сотен файлов я должен вычислить время, когда 0,01, 0,02, 0,03 ... 0,97, 0,98, 0,99 деградируют. Затем я хочу рассчитать среднее значение i. е. все время, когда 0,01 деградируют. То же самое для 0,02, 0,03 и так далее. В итоге у меня должно быть 99 раз в порядке возрастания.

Можно ли прикрепить файлы? Я не нашел возможности сделать это.

Изменить 2:

Выход dput для DataList полученного

names <- dir(pattern="Data.txt") 
datalist <- lapply(names, read.table, header=TRUE) 

является:

> dput(head(datalist[[1]])) 
structure(list(Time = c(0L, 60L, 120L, 180L, 240L, 300L), Sub0_Abs = c(1.49899, 
1.49568, 1.49544, 1.49533, 1.49521, 1.49507), Sub0_Rel = c(1, 
0.9978, 0.9976, 0.9976, 0.9975, 0.9974), Sub1_Abs = c(1.49899, 
1.49899, 1.49899, 1.49899, 1.49899, 1.49899), Sub1_Rel = c(1, 
1, 1, 1, 1, 1), TP = c(0.15, 0.1579, 0.1584, 0.1586, 0.1589, 
0.1592), TA = c(0.13, 0.16, 0.18, 0.18, 0.18, 0.22), Sub_Inflow = c(0, 
0, 0, 0, 0, 0)), .Names = c("Time", "Sub0_Abs", "Sub0_Rel", "Sub1_Abs", 
"Sub1_Rel", "TP", "TA", "Sub_Inflow"), row.names = c(NA, 6L), class = "data.frame") 

> dput(head(datalist[[2]])) 
structure(list(Time = c(0L, 60L, 120L, 180L, 240L, 300L), Sub0_Abs = c(1.49899, 
1.49284, 1.49234, 1.49207, 1.49176, 1.49141), Sub0_Rel = c(1, 
0.9959, 0.9956, 0.9954, 0.9952, 0.9949), Sub1_Abs = c(1.49899, 
1.49899, 1.49899, 1.49899, 1.49899, 1.49899), Sub1_Rel = c(1, 
1, 1, 1, 1, 1), TP = c(0.15, 0.1647, 0.1658, 0.1664, 0.1671, 
0.1679), TA = c(0.13, 0.21, 0.25, 0.25, 0.25, 0.37), Sub_Inflow = c(0, 
0, 0, 0, 0, 0)), .Names = c("Time", "Sub0_Abs", "Sub0_Rel", "Sub1_Abs", 
"Sub1_Rel", "TP", "TA", "Sub_Inflow"), row.names = c(NA, 6L), class = "data.frame") 

Соответствующие столбцы Время, Sub0_Rel и Sub1_Rel.В моем предыдущем вопросе я попытался немного сократить имена.

+1

Вы бы реальную пользу от обучения использовать 'lapply' и' sapply '. Они на самом деле довольно просты в использовании. Если бы вы предоставили некоторые воспроизводимые данные в своем вопросе, людям было бы легче помочь вам. – Roland

+0

Здравствуйте, Роланд, благодарю вас за помощь. Я стараюсь учиться, изучая примеры, но это трудно понять, потому что это не так «интуитивно» с первого взгляда. ... Я добавил некоторые примеры данных, чтобы представить структуру данных. – Hanna

ответ

0

Как @Roland сказал, вам сложно помочь без каких-либо данных примера. Я сделал попытку написать код для набора значений z, но, конечно (без данных), код не тестировался. Возможно, это поможет вам начать работу.

# try with a bunch of z values 
z <- c(0.25, 0.45, 0.72, 0.83) 
a <- 1-z 

setwd("H:/...") 
# read in all of the data and save to a list 
names <- dir(pattern="Data.txt") 
datalist <- lapply(names, read.table, header=TRUE) 
matchs <- lapply(datalist, function(dat) 
    cbind(dat[which.min(abs(dat$Sub1-a)), ]), dat[which.min(abs(dat$Sub2-a)), ]) 

Прямо здесь теряюсь, потому что я не уверен, что вы пытаетесь построить ...

+0

Благодарим вас за помощь. Я пробовал ваш код, но я получаю сообщение об ошибке «Object» dat 'not found' ... – Hanna

+0

Если вы публикуете результаты для следующих двух команд, я попытаюсь устранить неполадки. 'dput (head (datalist [[1]]))' и 'dput (head (datalist [[2]]))'. –

+0

Thx, я отредактировал свой вопрос и добавил вывод dput. – Hanna

0

Хорошо, у меня была идея, что может сделать вещи немного проще. Как насчет использования линейной интерполяции вместо того, чтобы находить ближайшее значение sub для каждого числа в длинной последовательности? Вы можете сделать это с помощью функции approx(). Например, определите функцию для вычисления среднего времени для последовательности subs.

mean.time <- function(sub, time, points=seq(0.01, 0.99, by=0.01)) { 
    linear.interp <- approx(x=sub, y=time, xout=points) 
    mean(linear.interp$y, na.rm=TRUE) 
    } 

Затем вы можете применить эту функцию к каждому элементу вашего списка кадров данных, один раз для sub1 и один раз для sub2. (Я предположил, что вы были заинтересованы в Sub0_Rel и Sub1_Rel. Если это не так, то вам придется изменить эту часть кода.)

match1 <- sapply(datalist, function(dat) mean.time(dat$Sub0_Rel, dat$Time)) 
match2 <- sapply(datalist, function(dat) mean.time(dat$Sub1_Rel, dat$Time))