根据另一个因素重新排序因素级别

问题描述 投票:0回答:2

我有一个数据框

data
如下。

data <- structure(list(fac1 = structure(c(6L, 16L, 4L, 14L, 1L, 7L, 3L, 
                                          2L, 15L, 10L, 11L, 9L, 8L, 5L, 13L, 12L), .Label = c("dd85", 
                                                                                               "ee01", "ee12", "ee78", "gs85", "jj45", "jj63", "qe89", "qq74", 
                                                                                               "tt23", "tt78", "vd41", "vd51", "ww77", "yy25", "yy85"), class = "factor"), 
                       fac2 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 
                                          3L, 3L, 4L, 4L, 4L, 4L), .Label = c("md", "av", "zr", "kj"), class = "factor")), .Names = c("fac1", 
                                                                                                                                  "fac2"), row.names = c(NA, 16L), class = "data.frame")


levels(data$fac1)
levels(data$fac2)

data
   fac1 fac2
1  jj45   md
2  yy85   md
3  ee78   md
4  ww77   md
5  dd85   av
6  jj63   av
7  ee12   av
8  ee01   av
9  yy25   zr
10 tt23   zr
11 tt78   zr
12 qq74   zr
13 qe89   kj
14 gs85   kj
15 vd51   kj
16 vd41   kj

levels(data$fac1)
 [1] "dd85" "ee01" "ee12" "ee78" "gs85" "jj45" "jj63" "qe89" "qq74" "tt23" "tt78" "vd41" "vd51" "ww77" "yy25" "yy85"

levels(data$fac2)
[1] "md" "av" "zr" "kj"

如何在

fac1
的基础上重新排序
fac2
的级别?

我已经根据这个

问题
尝试过factor(data, levels=data[order(data$fac2),], ordered=TRUE),但它给出了两个级别。

factor(data, levels=data[order(data$fac2),], ordered=TRUE)
                                                    fac1                                                     fac2 
c(6, 16, 4, 14, 1, 7, 3, 2, 15, 10, 11, 9, 8, 5, 13, 12)        c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4) 
2 Levels: c(6, 16, 4, 14, 1, 7, 3, 2, 15, 10, 11, 9, 8, 5, 13, 12) < ...
r
2个回答
11
投票

假设我了解您的需求,您可以尝试对 data.frame 进行排序,然后将

fac1
作为级别(顺序)传递。

data$fac1 <- factor(data$fac1, levels = data[order(data$fac2), "fac1"])
levels(data$fac1)

> data
   fac1 fac2
1  jj45   md
2  yy85   md
3  ee78   md
4  ww77   md
5  dd85   av
6  jj63   av
7  ee12   av
8  ee01   av
9  yy25   zr
10 tt23   zr
11 tt78   zr
12 qq74   zr
13 qe89   kj
14 gs85   kj
15 vd51   kj
16 vd41   kj
> levels(data$fac1)
 [1] "jj45" "yy85" "ee78" "ww77" "dd85" "jj63" "ee12" "ee01" "yy25"
[10] "tt23" "tt78" "qq74" "qe89" "gs85" "vd51" "vd41"

0
投票

您还可以将

forcats::fct_reorder()
order()
一起使用,即
forcats::fct_reorder(this order(other))

library(forcats)
data <- data.frame(
  fac1 = as.factor(c("jj45","yy85","ee78",
                     "ww77","dd85","jj63","ee12","ee01","yy25",
                     "tt23","tt78","qq74","qe89","gs85","vd51","vd41")),
  fac2 = factor(c("md","md","md","md",
                     "av","av","av","av","zr","zr","zr","zr","kj",
                     "kj","kj","kj"), levels = c("md", "av", "zr", "kj"))
)

fct_reorder(data$fac1, order(data$fac2))
#>  [1] jj45 yy85 ee78 ww77 dd85 jj63 ee12 ee01 yy25 tt23 tt78 qq74 qe89 gs85 vd51
#> [16] vd41
#> 16 Levels: jj45 yy85 ee78 ww77 dd85 jj63 ee12 ee01 yy25 tt23 tt78 qq74 ... vd41

## Check is same as answer by Roman?
all.equal(levels(fct_reorder(data$fac1, order(data$fac2))),
          levels(factor(data$fac1, levels = data[order(data$fac2), "fac1"])))
#> [1] TRUE

创建于 2024-05-22,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.