添加未使用的因子水平

马丁·洛瑞

我有一个简单的问题无法解决:我想绘制一个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()) 

可以看到,我将两个因素的第二个要素“工作”归因于这些要素,但它绘制了“自由”字样。令人不安的是,因子mon只有1个级别,而不是2个可能的级别。如果我将多个级别归因于,它会给出另一个图mon

mon   <- as.data.frame(matrix(as.factor(rep(c(f[1], f[2]), times = 4)), nrow = 4))

..并重新运行该图。即使从最初的两个级别中进行选择,也无法分配另一个级别:

mon[1,1] <- f[1]

我尝试了很多有levelsrelevelorder等没有成功。有人有主意吗?

格雷戈尔·托马斯(Gregor Thomas)

矩阵无法容纳因素。当你把一个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()) 

在此处输入图片说明

如果要使色标更加安全,可以将其添加namesvalues矢量中,然后再将其放入色标中:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章