R:构造嵌套for循环和保存结果的问题

时间:2013-06-20 14:29:41

标签: r for-loop

这是一个基于我之前提出的问题的问题:Read many files, compute something, save results in dataframe (R)

我仍然有大约100个文件来自模拟数据。主题是两种物质的降解,因此我有3个相关的列:时间(以分钟为单位),物质1的相对浓度(Sub1,从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循环中计算的。

首先,我认为未来的想法可能会更好地与数据主义者合作,例如: G。为了绘制这些文件中的一些数据,我做了:

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)
   }}

我想构建一个新的数据框,其中每个级别的结果(从0.01到1)保存在一个列中。然后我可以计算每个colormn的平均值。但我已经无法计算数据框了。

也许还有一种更简单的方法来获得不同时间序列的平均值。

我真的很感激任何帮助。

编辑: 我很难提供样本数据,因为我有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

我想计算平均值,所以对于100个文件中的每一个,我必须计算时间,当0.01,0.02,0.03 ... 0.97,0.98,0.99降级时。然后我想计算i的平均值。即所有时间,0.01降级。同样适用于0.02,0.03等。最后,我应该按升序排列99次。

是否可以附加文件?我发现没有选择这样做。

编辑2:

通过

获得的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")

相关列为Time,Sub0_Rel和Sub1_Rel。在我之前的问题中,我试图缩短名称。

2 个答案:

答案 0 :(得分: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)), ])

就在这附近我迷路了,因为我不确定你想要绘制的是什么......

答案 1 :(得分:0)

好吧,我有一个想法,可能会让事情变得更简单。如何使用线性插值而不是为长序列中的每个数字找到最近的子值?您可以使用approx()功能执行此操作。例如,定义一个函数来计算一系列潜艇的平均时间。

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_RelSub1_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))