[英]add factor levels that are not in use
我有一個我無法解決的簡單問題:我想用因子繪制一個data.frame
(一個月),其中有時缺少水平。 R 只對現有級別進行屬性,因此如果存在一個、兩個或更多個級別,我的圖會有所不同。
這里有一個例子:
library(ggplot2)
library(reshape2)
f <- factor(c("Free", "Work"))
mon <- as.data.frame(matrix(as.factor(rep(f[2], times = 8)), nrow = 4))
colnames(mon) <- c("A", "B")
mt <- t(as.matrix(rev(data.frame(as.matrix(mon))))) # change order of y
m <- melt(mt)
col <- c("azure", "orange")
ggplot(m, aes(x = Var2, y = Var1, fill = value)) +
geom_tile(colour="grey10") +
scale_fill_manual(values = col, labels = f, name = NULL) +
theme(panel.background = element_rect(fill = "white"), axis.ticks = element_blank()) +
theme(axis.title.x = element_blank(), axis.title.y = element_blank())
如您所見,我將 2 個因素的第二個元素“工作”歸因於元素,但它繪制了“自由”。 令人不安的是, mon
的因子只有 1 個級別,而不是 2 個可能的級別。 如果我將幾個級別歸因於mon
它會給出另一個圖:
mon <- as.data.frame(matrix(as.factor(rep(c(f[1], f[2]), times = 4)), nrow = 4))
..並重新運行上面的情節。 也不能分配另一個級別,即使它是從最初的 2 個級別中選擇的:
mon[1,1] <- f[1]
我嘗試了很多levels
, relevel
, order
等,但沒有成功。 有沒有人有想法?
矩陣不能容納因子。 當您將一個factor
放入matrix
,它會被強制轉換為character
,並且會丟失未使用的級別。 由於這個(和其他類轉換)原因, as.data.frame(matrix(...)))
是一個壞習慣。
這是一種在不丟失因子水平的情況下盡可能接近地復制數據轉換的方法:
f <- factor(c("Free", "Work"))
x= rep(f[2], 4)
mon <- data.frame(A = x, B = x)
str(mon)
# 'data.frame': 4 obs. of 2 variables:
# $ A: Factor w/ 2 levels "Free","Work": 2 2 2 2
# $ B: Factor w/ 2 levels "Free","Work": 2 2 2 2
## looks good
# What is y? What's the point?
#mt <- t(as.matrix(rev(data.frame(as.matrix(mon))))) # change order of y
mon$id = 1:nrow(mon)
m <- reshape2::melt(mon, id.vars = "id", factorsAsStrings = FALSE)
levels(m$value)
# [1] "Free" "Work"
## looks good
現在,當我們開始繪圖時,在比例中指定drop = FALSE
以在圖例中包含未使用的級別。 (如果您不想顯示未使用的級別,請使用默認的drop = TRUE
。)由於級別已經存在,我們不需要自定義labels
。
col <- c("azure", "orange")
ggplot(m, aes(x = id, y = variable, fill = value)) +
geom_tile(colour="grey10") +
scale_fill_manual(values = col, name = NULL, drop = FALSE) +
theme(panel.background = element_rect(fill = "white"), axis.ticks = element_blank()) +
theme(axis.title.x = element_blank(), axis.title.y = element_blank())
如果您想對色標更加安全,可以在將其放入色標之前將names
添加到values
向量中:
names(col) = levels(f)
獲取數據的另一種方法是不必擔心轉換過程中的級別,並在最后使用適當的級別重新分解:
# your original code:
f <- factor(c("Free", "Work"))
mon <- as.data.frame(matrix(as.factor(rep(f[2], times = 8)), nrow = 4))
colnames(mon) <- c("A", "B")
mt <- t(as.matrix(rev(data.frame(as.matrix(mon))))) # change order of y
m <- melt(mt)
# add this at the end
m$value = factor(m$value, levels = levels(f))
# check that it looks good:
str(m$value)
# Factor w/ 2 levels "Free","Work": 2 2 2 2 2 2 2 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.