Dataset is in Factors No Continuous Values
I am using a categorical variable to color the lines, labels, and ribbons in a plot created by ggplot. Numerical thresholds are used to distinguish three different categories, and those categories are assigned either green, blue, or red lines/labels/ribbons. What I have works well in most scenarios, but there is one scenario where it falls apart. If I have data that transitions from one category to another, and then back to the original, the data in the first and final group is treated as if it were continuous. A minimal reproducible example follows, but first I include two data sets in CSV format that are read into dataframes (a "good" set followed by a "bad" set):
GOOD DATA:
drug,dose,value,samples,conf,lower,upper verapamil,1,72.56565,800,0.95,69.8194345,75.33907125 verapamil,2,72.44075,800,0.95,69.44212025,75.1824985 verapamil,3,70.79216,800,0.95,67.52461925,73.76032875 verapamil,4,68.91252,800,0.95,65.1242505,71.9545765 verapamil,5,66.91399,800,0.95,62.3466355,70.25188075 verapamil,6,65.07556,800,0.95,59.776704,68.484171 verapamil,7,63.52973,800,0.95,57.2319935,66.67006225 verapamil,8,62.22067,800,0.95,54.90753525,65.26015775 verapamil,9,60.65876,800,0.95,52.87391825,64.0331005 verapamil,10,59.57872,800,0.95,50.9498555,63.08050025 verapamil,15,56.44804,800,0.95,42.66295,73.614082 verapamil,20,55.23902,800,0.95,29.75458325,109.266985 verapamil,25,55.16381,800,0.95,23.006594,120.3280525
BAD DATA:
drug,dose,value,samples,conf,lower,upper ranolazine,1,70.481,800,0.95,67.05068975,73.7571095 ranolazine,2,70.37064,800,0.95,66.865067,73.9150805 ranolazine,3,69.93621,800,0.95,66.70263375,74.0239275 ranolazine,4,69.53205,800,0.95,66.58873925,73.8851205 ranolazine,5,69.15334,800,0.95,66.0595545,73.833377 ranolazine,6,68.59902,800,0.95,65.4348675,73.7104295 ranolazine,7,68.09159,800,0.95,64.82512825,73.588261 ranolazine,8,67.53056,800,0.95,63.9937705,73.09860775 ranolazine,9,66.89892,800,0.95,63.253657,72.61998375 ranolazine,10,66.58314,800,0.95,62.4634455,71.94309325 ranolazine,15,67.00043,800,0.95,49.49385475,70.59155425 ranolazine,20,75.5989,800,0.95,33.52134225,86.43966325 ranolazine,25,88.64885,800,0.95,31.974256,104.275215
And the R script:
infile <-"good.csv" #infile <-"bad.csv" cidf <- read.csv(file = infile, stringsAsFactors = FALSE) # prepare results for plotting cidf[,c("value","lower","upper")]<-cidf[,c("value","lower","upper")]/1e3 # convert units # assign value used to color lines, labels, and ribbons for (row in 1:nrow(cidf)) { if(is.na(cidf$value[row])) { cidf$CiPA[row] = 2 } else if (cidf$value[row] > 0.0689) { cidf$CiPA[row] = 0 } else if (cidf$value[row] > 0.0579) { cidf$CiPA[row] = 1 } else cidf$CiPA[row] = 2 } cidf$CiPA<-factor(cidf$CiPA, levels=c(2,1,0)) # THIS IS CAUSING THE WEIRD ISSUE WITH THE RANOLAZINE PLOT! #cidf$CiPA<-factor(cidf$CiPA, levels=c(0)) #cidf$CiPA<-factor(cidf$CiPA, levels=c(1)) #cidf <- droplevels(cidf) #cidf$CiPA <- as.numeric(as.character(cidf$CiPA)) # data frame of drug labels newdf<-aggregate(dose ~ drug, data=cidf, max) colnames(newdf)<-c("drug","max") newdf<-merge(cidf,newdf,by.x="drug",by.y="drug",all=TRUE) newdf<-newdf[newdf$dose==newdf$max,] tofix<-which(is.na(newdf$value)) for(fixi in tofix) newdf[fixi,"value"]<-mean(as.numeric(newdf[fixi, c("lower","upper")])) figfile<-"plot.pdf" pdf(figfile, width=8, height=4.5) p<-ggplot(cidf, aes(dose, value, group=interaction(drug, CiPA))) + scale_color_manual(values = c("2" = "#e82929", "1"="#337cb4", "0"="#44ae52")) + scale_fill_manual(values = c("2" = "#e82929", "1"="#337cb4", "0"="#44ae52"), name="fill") + geom_line(aes(color=CiPA)) + geom_ribbon(aes(ymin=lower, ymax=upper, fill = CiPA), alpha=0.3) + geom_text(data=newdf, aes(label=drug, color=CiPA), hjust=-0.2, vjust=0.5, size=3, show.legend=F) + coord_cartesian(xlim=c(0,max(cidf$dose)*1.2)) + xlab(~"Concentration (\u00D7"~C[max]*")") + ylab(~"qNet ("*mu*"C/"*mu*"F)") + theme_bw() + theme(legend.position="none") x11(title="Plot") # switch dev from pdf to x11 show(p) # show the plot in a window while(names(dev.cur()) !='pdf'){ # dev changes from x11 back to pdf when window is closed print(names(dev.cur())) # this conditional is required, otherwise window closes immediately Sys.sleep(1) } print(p) dev.off()
I am working in Ubuntu, so if you are not you can remove the X11 plot show. Using the "good" data set, the plot is still not quite right. I have to manipulate the data to add some extra points at thresholds where colors change (I did not want to include that function in this example as it is large and isn't directly involved with the problem at hand). When I do so the plot comes out as below:
We travel from one categorical variable, then to the next, and finally the third. However, using the "bad" data set, the issue is that we travel from one categorical variable, to another, but then back to the first. In this case the first and third blocks of data are treated as if they are continuous instead of discrete. This is more easily seen when you change the factor levels from c(2,1,0)
to c(1)
or c(0)
. What I end up with is this:
A line is added connecting the data point at Cmax = 5 to Cmax = 15, treating these two discrete sets as if they are continuous. Then the middle set of data with the different categorical variable is by itself, not connected to the adjacent data points. This is clearly not what I am looking for and I cannot figure out where I am going wrong. If I try to use numerical values, I end up with the error:
Error: Continuous value supplied to discrete scale
Dropping levels also did not work. I am not sure if there is a simple solution here, but I expect that there would be. Any pointers would be greatly appreciated.
EDIT: The output of dput(cidf) was requested. For the "good" data I receive:
> dput(cidf) structure(list(drug = c("verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil", "verapamil" ), dose = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 15L, 20L, 25L), value = c(0.07256565, 0.07244075, 0.07079216, 0.06891252, 0.06691399, 0.06507556, 0.06352973, 0.06222067, 0.06065876, 0.05957872, 0.05644804, 0.05523902, 0.05516381), samples = c(800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L ), conf = c(0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95), lower = c(0.0698194345, 0.06944212025, 0.06752461925, 0.0651242505, 0.0623466355, 0.059776704, 0.0572319935, 0.05490753525, 0.05287391825, 0.0509498555, 0.04266295, 0.02975458325, 0.023006594), upper = c(0.07533907125, 0.0751824985, 0.07376032875, 0.0719545765, 0.07025188075, 0.068484171, 0.06667006225, 0.06526015775, 0.0640331005, 0.06308050025, 0.073614082, 0.109266985, 0.1203280525 ), CiPA = structure(c(3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L), .Label = c("2", "1", "0"), class = "factor")), row.names = c(NA, -13L), class = "data.frame")
And for the "bad" data I get:
> dput(cidf) structure(list(drug = c("ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine", "ranolazine" ), dose = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 15L, 20L, 25L), value = c(0.070481, 0.07037064, 0.06993621, 0.06953205, 0.06915334, 0.06859902, 0.06809159, 0.06753056, 0.06689892, 0.06658314, 0.06700043, 0.0755989, 0.08864885), samples = c(800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L, 800L), conf = c(0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95, 0.95), lower = c(0.06705068975, 0.066865067, 0.06670263375, 0.06658873925, 0.0660595545, 0.0654348675, 0.06482512825, 0.0639937705, 0.063253657, 0.0624634455, 0.04949385475, 0.03352134225, 0.031974256), upper = c(0.0737571095, 0.0739150805, 0.0740239275, 0.0738851205, 0.073833377, 0.0737104295, 0.073588261, 0.07309860775, 0.07261998375, 0.07194309325, 0.07059155425, 0.08643966325, 0.104275215), CiPA = structure(c(3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L), .Label = c("2", "1", "0"), class = "factor")), row.names = c(NA, -13L), class = "data.frame")
Source: https://stackoverflow.com/questions/68584486/r-factor-level-in-ggplot-treated-as-continuous-data-set
0 Response to "Dataset is in Factors No Continuous Values"
Post a Comment