试图使类别值在条形图中排序

Trying to keep category values sorted in barplot

我有一个包含大约 3000 个观察值的数据框。我不仅分析整体,还分析子样本,我创建如下:

SNIIPPET 1:

allophone.count.test <- subset (merged.data.for.study, Environment %in% curr.phon.env)

我有一些数据,其中特定类别的值(下面数据中的"Allophone")需要在条形图中以特定顺序显示,如下所示:

[p], [p̚], [pʰ], [p͡ɸ], [ɸ], [b], [b͡β], [β], OTHER, ∅

为了建立正确的顺序,我在部分数据处理过程中为上述值分配了编号。然后值如下所示:

01. [p], 02. [p̚], 03. [pʰ], 04. [p͡ɸ], 05. [ɸ], 06. [b], 07. [b͡β], 08. [β], 09. OTHER, 10. ∅

这是一个示例数据框。请注意,在此阶段,Allophone 和 Allophone.Backup 包含相同的值,以便稍后检查错误):

allophone.count.test <- read.table(
    header=TRUE, sep="\t", text='Region Phoneme Allophone   Count   Total.Count Percentage  Allophone.Backup
LocationA   p   01. [p] 16  92  17.4    01. [p]
LocationA   p   02. [p̚]    4   92  4.3 02. [p̚]
LocationA   p   05. [ɸ] 8   92  8.7 05. [ɸ]
LocationA   p   06. [b] 5   92  5.4 06. [b]
LocationA   p   08. [β] 55  92  59.8    08. [β]
LocationA   p   09. OTHER   1   92  1.1 09. OTHER
LocationA   p   10. ∅   3   92  3.3 10. ∅
LocationB   p   01. [p] 19  136 14  01. [p]
LocationB   p   03. [pʰ]    1   136 0.7 03. [pʰ]
LocationB   p   05. [ɸ] 14  136 10.3    05. [ɸ]
LocationB   p   06. [b] 7   136 5.1 06. [b]
LocationB   p   08. [β] 88  136 64.7    08. [β]
LocationB   p   10. ∅   7   136 5.1 10. ∅'
)

一切都很好,我尝试过的所有绘图工具(barplot、ggplot2 和我目前正在使用的 wrapper)都会按字母数字顺序对这些值进行适当排序,所以当我绘图时添加数字的数据都很好。不幸的是,这些数字使这些情节看起来非常业余,并且不会被接受出版。所以我需要在去掉数字的同时保持正确的顺序。

问题是,一旦我尝试绘制没有数字的值,我尝试的所有绘图工具都会恢复为按字母顺序对它们进行排序。

我发现针对此问题的大多数建议解决方案都将其转换为一个因数。以下是我用来 (1) 将其转换为一个因子和 (2) 去掉前导数字 + 句点 + space:

的代码

片段 2:

allophone.count.test$Allophone <- factor (allophone.count.test$Allophone)
allophone.count.test$Allophone <- gsub ("[0-9][0-9]\. ", "", allophone.count.test$Allophone, perl=TRUE)

这个 看起来 像它一样工作,如下所示,因为同位异音值没有前导数字、句点或 space,并且保留了正确的顺序:

    Region  Phoneme Allophone   Count   Total.Count Percentage  Allophone.Backup
1   LocationA   p   [p] 16  92  17.4    01. [p]
2   LocationA   p   [p̚]    4   92  4.3 02. [p̚]
3   LocationA   p   [ɸ] 8   92  8.7 05. [ɸ]
4   LocationA   p   [b] 5   92  5.4 06. [b]
5   LocationA   p   [β] 55  92  59.8    08. [β]
6   LocationA   p   OTHER   1   92  1.1 09. OTHER
7   LocationA   p   ∅   3   92  3.3 10. ∅
8   LocationB   p   [p] 19  136 14.0    01. [p]
9   LocationB   p   [pʰ]    1   136 0.7 03. [pʰ]
10  LocationB   p   [ɸ] 14  136 10.3    05. [ɸ]
11  LocationB   p   [b] 7   136 5.1 06. [b]
12  LocationB   p   [β] 88  136 64.7    08. [β]
13  LocationB   p   ∅   7   136 5.1 10. ∅

但是然后我开始绘图,一切都再次按字母顺序排列(我在我的工作中没有使用 ggplot2,而是我链接到的包装器,但出于说明目的,ggplot2 可以):

片段 3:

ggplot(allophone.count.test, aes(factor(Allophone), Count, fill = Region)) + 
    geom_bar(stat="identity", position = "dodge") + 
    scale_fill_brewer(palette = "Set1")

现在,我找到了一个部分解决方案 ONLY 当 Allophone 的所有可能值都存在时(即它们在我正在处理的特定子样本中有一个计数 > 1)在给定时间处理)。即手动将 number-free 版本的 Allophone 值分配给因子作为标签:

片段 4:

allophone.count.test$Allophone <- factor (allophone.count.test$Allophone, labels = c("[p]", "[p̚]", "[pʰ]", "[p͡ɸ]", "[ɸ]", "[b]", "[b͡β]", "[β]", "OTHER", "∅"))

但是,这是一个非常 un-robust 的解决方案 -- Allophone 有 10 个可能的值,并且它们并不总是全部存在于给定的子样本中(例如我在此处提供的那个) .发生这种情况时,R 就会停止。

是否有更强大的方法来完成我想用标签做的事情?(或者任何其他方式,就此而言?)

我能想到的最佳尝试(我既不是程序员也不是统计学家)惨遭失败——它为许多值分配了错误的标签(比较 Allophone 和 Allophone.Backup 开始第三行):

片段 5:

allophone.count.test$Allophone <- factor (
    allophone.count.test$Allophone, labels = unique (
        gsub ("[0-9][0-9]\. ", "", allophone.count.test$Allophone, perl=TRUE)
    )
)

    Region  Phoneme Allophone   Count   Total.Count Percentage  Allophone.Backup
1   LocationA   p   [p] 16  92  17.4    01. [p]
2   LocationA   p   [p̚]    4   92  4.3 02. [p̚]
3   LocationA   p   [b] 8   92  8.7 05. [ɸ]
4   LocationA   p   [β] 5   92  5.4 06. [b]
5   LocationA   p   OTHER   55  92  59.8    08. [β]
6   LocationA   p   ∅   1   92  1.1 09. OTHER
7   LocationA   p   [pʰ]    3   92  3.3 10. ∅
8   LocationB   p   [p] 19  136 14.0    01. [p]
9   LocationB   p   [ɸ] 1   136 0.7 03. [pʰ]
10  LocationB   p   [b] 14  136 10.3    05. [ɸ]
11  LocationB   p   [β] 7   136 5.1 06. [b]
12  LocationB   p   OTHER   88  136 64.7    08. [β]
13  LocationB   p   [pʰ]    7   136 5.1 10. ∅

下面就差不多了。它试图将 leading-numberless 形式分配给 Allophone 作为标签。但它失败了:

片段 6:

allophone.count.test$Allophone <- factor (
    allophone.count.test$Allophone, labels = gsub ("[0-9][0-9]\. ", "", allophone.count.test$Allophone, perl=TRUE)
)

Error in factor(allophone.count.test$Allophone, labels = gsub("[0-9][0-9]\. ",  : 
  invalid 'labels'; length 13 should be 1 or 8

当我尝试创建关卡来保存裸变音值时,我得到了一个不同的错误:

片段 7:

allophone.count.test$Allophone <- factor (
    allophone.count.test$Allophone, levels = gsub ("[0-9][0-9]\. ", "", allophone.count.test$Allophone, perl=TRUE)
)

Warning message:
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated

如果有人能给我任何帮助,我将不胜感激。重申一下,期望的结果是一个条形图,其中在删除数字时保留同位素向量的编号值的顺序。

(编辑:我已经为任何想要引用特定代码的人添加了 "Snippet" headers,因为这个问题很长)。

这是一个简化的示例,显示了其工作原理的逻辑:

# specify the order of the variable you want:
levs <- c("[p]", "[β]", "OTHER", "∅")

# here's some example data I prepared earlier:
test <- data.frame(
  Region = rep(c("LocationA","LocationB"), c(4,4)),
  Allophone = levs[c(1,3,2,4,3,2,1,4)],
  Count = c(16, 4, 8, 5, 55, 1, 3, 19),
  stringsAsFactors=FALSE
)

#     Region Allophone Count
#1 LocationA       [p]    16
#2 LocationA     OTHER     4
#3 LocationA       [ß]     8
#4 LocationA         Ø     5
#5 LocationB     OTHER    55
#6 LocationB       [ß]     1
#7 LocationB       [p]     3
#8 LocationB         Ø    19

# convert the Allophone variable with the specified order:
test$Allophone <- factor(test$Allophone, levels=levs)

# do the plotting:    
ggplot(test, aes(Allophone, Count, fill = Region)) + 
    geom_bar(stat="identity", position = "dodge") + 
    scale_fill_brewer(palette = "Set1")