簡體   English   中英

R:ggplot 中的因子水平被視為連續數據集

[英]R: Factor level in ggplot treated as continuous data set

我正在使用分類變量為 ggplot 創建的圖中的線條、標簽和色帶着色。 數值閾值用於區分三個不同的類別,這些類別被指定為綠色、藍色或紅色線條/標簽/色帶。 我在大多數情況下都運行良好,但有一種情況會崩潰。 如果我的數據從一個類別轉換到另一個類別,然后又返回到原始類別,則第一組和最后一組中的數據將被視為連續數據。 下面是一個最小的可重現示例,但首先我包含兩個 CSV 格式的數據集,它們被讀入數據幀(一個“好”集,然后是一個“壞”集):

好數據:

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

壞數據:

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

和 R 腳本:

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

我在 Ubuntu 中工作,所以如果你不是,你可以刪除 X11 繪圖顯示。 使用“好”的數據集,情節仍然不太正確。 我必須操縱數據以在顏色發生變化的閾值處添加一些額外的點(我不想在本示例中包含該函數,因為它很大並且不直接涉及手頭的問題)。 當我這樣做時,情節如下:

帶有更新數據的好圖

我們從一個分類變量開始,然后到下一個,最后是第三個。 然而,使用“壞”數據集,問題是我們從一個分類變量移動到另一個,然后又回到第一個。 在這種情況下,第一個和第三個數據塊被視為是連續的而不是離散的。 當您將因子水平從c(2,1,0)更改為c(1)c(0)時,更容易看到這一點。 我最終得到的是這樣的:

壞情節

添加一條線將 Cmax = 5 處的數據點連接到 Cmax = 15,將這兩個離散集視為連續的。 那么具有不同分類變量的中間數據集是獨立的,不連接到相鄰的數據點。 這顯然不是我想要的,我無法弄清楚我哪里出錯了。 如果我嘗試使用數值,最終會出現錯誤:

Error: Continuous value supplied to discrete scale

降低水平也不起作用。 我不確定這里是否有一個簡單的解決方案,但我希望會有。 任何指針將不勝感激。


編輯:請求 dput(cidf) 的輸出。 對於我收到的“好”數據:

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

對於我得到的“壞”數據:

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

這能解決您的問題嗎? 我添加了一個變量來分隔 CiPA 中的每個更改,即使它返回到已使用的更改。 這樣它就不會連接共享 CiPA 級別的非連續部分。

library(dplyr)
cidf_bad %>%
  arrange(drug, dose) %>%
  group_by(drug) %>%
  mutate(CiPA_grp = cumsum(as.numeric(CiPA) != lag(as.numeric(CiPA), default = Inf))) %>%
ungroup() %>%

ggplot(aes(dose, value, group=interaction(drug, CiPA_grp))) + 
# the rest of your code

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM