Reputation: 2412
I know the title makes this sound very easy, but I have a For loop that graphs my data. As the values vary, so too does the limits of the X-axis (different start and end for each plot). However, I want to have a defined X-axis range that stays the same for all similar plots. This is complicated by the fact that there are ~40 possible ranges for the X that I want.
I have a data frame of the x-lims I would like to choose from, for each plot. It basically looks like:
Trait start end
A 123456 134567
B 234546 245678
C 234546 245678
D 345678 356789
and so on. So, if one loop gives me the values: Trait C, start = 235000 and end = 240000, I would like to automatically use the third set of default X-lims.
edit: added more info (Trait).
Upvotes: 1
Views: 207
Reputation: 6749
I'm not sure I totally follow the issue. If I'm understanding you correctly, you want to ensure that the range of each of your plots is 11111 (in this example, anyway), but the upper and lower values are going to vary significantly. So, right now, you're looking for a way to create a table of all the possible upper and lower bounds you might want, and then you want to look them up when you plot.
I'd propose that you could do it a lot more easily by simply writing the plot statement to ensure that the minimum and maximum are always 11111 apart.
Let's say you got start <- 235000, end <- 240000, and trait <- B during one loop iteration. Could you structure your code like this?
diff <- end-start
gap <- 11111-diff
plot(thing_you_plot,xlim(start-(gap/2),end+(gap/2))
With numbers:
diff <- 240000-235000 (5000)
gap <- 11111-5000 (6111)
plot(thing_you_plot,xlim(235000-(6111/2),240000+(6111/2))
(x limits are: 231944.5,243055.5, making the plot 11111 in length)
Obviously, if you wanted, you could use floor and ceiling functions to get round numbers instead of decimals. It's not clear from your question how the "trait" even really affects the dimensions; if you can have two traits (B and C) that are plotted using the same dimensions, why do you need the table at all? I think you can do a lot better just doing it for each plot using simple functions.
EDITED BASED ON REVISION:
Josh beat me to it, but here it is again since I had it almost all typed.
df <- data.frame(trait=c("A","B","C","D"),
start=c(123456,234546,234546,345678),
end=c(134567,245678,245678,356789))
trait <- "C"
start <- 235000
end <- 240000
xmin <- df[which(start > df$start & end < df$end & trait == df$trait),2]
xmax <- df[which(start > df$start & end < df$end & trait == df$trait),3]
Upvotes: 2
Reputation: 162321
If your displayed data.frame is called df
(and your are sure your variable end
will be greater than start
), this should work:
which(start > df$start & end < df$end)[1]
Revised to answer revised question
As you add more conditions, you can extend the logic above:
## Make your data easily reproducible for others
df <- read.table(text="Trait start end
A 123456 134567
B 234546 245678
C 234546 245678
D 345678 356789", header=TRUE)
## Set values from within your example loop
Trait <- "C"
start <- 235000
end <- 240000
## Get index of desired row
i <- which(Trait==df$Trait & start > df$start & end < df$end)[1]
## Extract xlim values in the form of a numeric vector
myxlim <- unname(unlist(df[i, c("start", "end")]))
myxlim
[1] 234546 245678
Upvotes: 4