过滤器 data.frame 以 R 中的有序因子为条件

filter data.frame conditional on ordered factor in R

我有一个长格式的大型数据框,我想在稍后将其转换为宽格式。每个 StudyId 都有几个注释者的条目。我想过滤数据框以仅包含一个注释器的每个 StudyID 的条目。优选地,遵循注释器的层次结构。意思是,如果第一个 AnnotatorID(某个列表的)存在,则保留这些条目,如果不存在,则查找第二个,依此类推。

下面是一些要复制的示例代码:

StudyId <- c("a", "a", "a", "a", "a", "b", "b", "b", "c", "c", "c", "c")
AnnotatorId <- c("Frank", "Frank", "Steffi", "Steffi", "Steffi", "Max", "Max", "Toni", "Frank", "Frank", "Annabelle", "Annabelle")

a <- data.frame(StudyId, AnnotatorId)

data.frame 由大约160 个变量和 3000 多个观察值。此示例中的 ID 已简化,但在我的数据框中,它们由数字和字母的混合组成,例如:“034e6cee-79e8-4e67-a27a-1ee2c187eaf4”。我猜,按字母顺序或最高值排序都不太可能有帮助。

到目前为止,我尝试对 AnnotatorId 的级别进行排序,但不知道如何遍历所有条目并仅保留 AnnotatorIds 在因子中的出现顺序。

a$AnnotatorId <- factor(a$AnnotatorId, 
                        levels = c(
                          "Max",
                          "Annabelle",
                          "Toni",
                          "Steffi",
                          "Frank"
                        ), ordered = TRUE)

最后我想要的是:

StudyId AnnotatorId
a Steffi
a Steffi
a Steffi
b Max
b Max
c Annabelle
c Annabelle

我是一个编程小白。因此,非常感谢任何帮助和指导。

您可以 group_by StudyId 和 filter:

StudyId <- c("a", "a", "a", "a", "a", "b", "b", "b", "c", "c", "c", "c")
AnnotatorId <- c("Frank", "Frank", "Steffi", "Steffi", "Steffi", "Max", "Max", "Toni", "Frank", "Frank", "Annabelle", "Annabelle")
a <- data.frame(StudyId, AnnotatorId)

a$AnnotatorId <- factor(a$AnnotatorId, 
                        levels = rev(c(
                          "Max",
                          "Annabelle",
                          "Toni",
                          "Steffi",
                          "Frank"
                        )), ordered = TRUE)

a %>% 
   group_by(StudyId) %>% 
   filter(AnnotatorId == max(AnnotatorId))

输出

# A tibble: 7 × 2
# Groups:   StudyId [3]
  StudyId AnnotatorId
  <chr>   <ord>      
1 a       Steffi     
2 a       Steffi     
3 a       Steffi     
4 b       Max        
5 b       Max        
6 c       Annabelle  
7 c       Annabelle 

我建议不要按顺序排列标称值。一个普通的 factor 就足够了,因为它的底层整数结构已经根据以 1 开头的级别“排序”。只需在 ave.

中使用 min
hier <- c("Max", "Annabelle", "Toni", "Steffi", "Frank")
a <- transform(a, AnnotatorId=factor(AnnotatorId, levels = hier))

a[as.logical(ave(as.integer(a$AnnotatorId), a$StudyId, FUN=\(x) x == min(x))), ]
#    StudyId AnnotatorId
# 3        a      Steffi
# 4        a      Steffi
# 5        a      Steffi
# 6        b         Max
# 7        b         Max
# 11       c   Annabelle
# 12       c   Annabelle

数据:

a <- structure(list(StudyId = c("a", "a", "a", "a", "a", "b", "b", 
"b", "c", "c", "c", "c"), AnnotatorId = c("Frank", "Frank", "Steffi", 
"Steffi", "Steffi", "Max", "Max", "Toni", "Frank", "Frank", "Annabelle", 
"Annabelle")), class = "data.frame", row.names = c(NA, -12L))