简体   繁体   中英

Rscript plot with loop over data

I apologies in advance if this question has already been answered but I have not been able to find what I need. I want to plot some results from files named data1.dat, data2.dat, ... I manage to import the data with a loop but I am unable to plot the results using a loop. Only the results from the first data is ploted. Below is the script that I used:

for(i in 1:3){
  assign( paste("data", i, sep=""),
  read.table(file=paste(paste("data", i, sep=""),"_lambda.dat",sep=""),head=TRUE, sep=" "))
}

#plot
for(i in 1:3){
  if(i==1){
    plot(data.frame(data1[1], data1[2]), xlim=c(-0.2, -7), ylim=c(0.31, 0.35), yaxt="n", type="l", xlab="", ylab="",lty="solid", col="red2", lwd=4, axes=TRUE)
  } else { 
    lines(data.frame(paste("data", i, "[1]", sep=""), paste("data", i, "[2]", sep="")) ,lty="twodash", col="deepskyblue4", lwd=4)
  }
}

The problem is related to the part after the "else". The data is not ploted and I don't get any error message either.

Thanks for the help,

There is hardly ever a meaningful use for assign . What you do above could be much more easily be done using lists:

# Read the data by inserting each data.frame into our list.
data <- list()
for (i in 1:3) {
    data[[i]] <- data.frame(runif(10), rnorm(10)) # Replace with your call to read.table.
}

# As we are lazy, we can pre-save our styles and just use them later
ltys <- c('solid', 'twodash', 'twodash')
cols <- c('red', 'deepskyblue4', 'deepskyblue4')

# Creating the empty plot first allows us to do everything else with lines. Note that there are a ton of different ways to archive this. 
plot(NA, xlim=c(0,1), ylim=c(-2,2))
# And now we just may access the data by using the lists. 
for (i in 1:length(data)) {
    d <- data[[i]]
    lines(d[,1], d[,2], lty=ltys[i], col=cols[i], lwd=4)
}

If we are aiming for elegance, we could even use a totally different approach:

# This time we will read all data into one data.frame.
# This requires the data to be of the same form, however. 
data <- data.frame()
for (i in 1:3) {
    d <- data.frame(x=runif(10), y=rnorm(10))
    # Here is the trick: We add the index i (or a file name, or something totally different) as a separate column.
    data <- rbind(data, cbind(d, group=i))
}
# This is just to ensure that our group column is a factor.
data$group <- as.factor(data$group)

# Now, plotting could be done by various ways. Personally, I like the elegance of ggplot2. 
library(ggplot2)
qplot(x,y,data=data, col=group, geom="line")

This is because you are effectively only using data1 .

The first loop can be expanded to

data1 = read.table('data1_lambda.dat', ...)
data2 = read.table('data2_lambda.dat', ...)
data3 = read.table('data3_lambda.dat', ...)

whereas your second loop is a bit buggy and the cause of the fault. If I expand the loop, what happens is:

plot(data.frame(data1[1], data1[2]), ...)
lines(data.frame('data2[1]', 'data2[2]', ...)
lines(data.frame('data3[1]', 'data3[2]', ...)

ie what you think is fetching data2 and data3 , you are really only using the strings 'data2' and 'data3' (note the quotation marks).

Without assuming too much of your data and restructuring you entire code, this should do the trick (for the second loop). Since you only have three data-files, looping seems a bit extensive contra the problems they are introducing.

plot(data.frame(data1[1], data1[2]), xlim=c(-0.2, -7), ylim=c(0.31, 0.35), yaxt="n", type="l", xlab="", ylab="",lty="solid", col="red2", lwd=4, axes=TRUE)
lines(data.frame(data2[1], data2[2]) ,lty="twodash", col="deepskyblue4", lwd=4)
lines(data.frame(data3[1], data3[2]) ,lty="twodash", col="deepskyblue4", lwd=4)

If you insist on looping, we could do:

for(i in 1:3){
  if(i==1){
    plot(data.frame(data1[1], data1[2]), xlim=c(-0.2, -7), ylim=c(0.31, 0.35), yaxt="n", type="l", xlab="", ylab="",lty="solid", col="red2", lwd=4, axes=TRUE)
  } else { 
    dat <- get(paste('data', i, sep=''))
    lines(data.frame(dat[1], dat[2]) ,lty="twodash", col="deepskyblue4", lwd=4)
  }
}

To further comment your code, in your read.table call, you have two nested paste calls, which in this case is unnecessary.

paste(paste("data", i, sep=""),"_lambda.dat",sep="") # could be done with paste(paste("data", i, "_lambda.dat",sep="")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM