如何根据另一列中值的出现设置因子水平顺序?
How to set factor levels order according to appearance of values in another column?
给定如下数据框:
label digit timediff
1 9 0
1 9 9
1 9 17
2 9 17
2 9 8
1 9 8
2 4 200
1 4 17
2 4 17
2 4 8
我正在尝试处理连续数字(这是 PIN 码分析)。
我的密码是 9460。
我想根据label和digit来分析timediff。
首先,我使用
创建了一个列
df$combined_factor <- with(df, interaction(label, digit))
但现在我需要根据数字外观来调整因子水平。
请指教如何才能"tell" combined_factor
列级别按数字出现的顺序排列(9 然后 4 然后 6 和 0)?
我探讨了这个问题:
但在我的情况下,我有标签。
例如combined_factor
可以是:
1.9
2.4
...
我希望它按数字顺序排列:1.9, ... 1.4, ... 1.6 ... 1.0, ... 2.9, ... 2.4, ... 2.6, ... 2.0 ....
label_digit timediff
<fct> <dbl>
1 1.9 0
2 1.9 9
3 1.9 17
4 1.9 17
5 1.9 8
6 1.9 8
7 1.4 200
8 1.4 17
9 1.4 17
10 1.4 8
levels(df$label_digit)
[1] "1.0" "2.0" "1.4" "2.4" "1.6" "2.6" "1.9" "2.9"
预计:
levels(df$label_digit):
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4" "2.6" "2.0"
由于您提供的可重现数据不佳,我将使用自己的数据:
d <- structure(list(label = c(1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 2L,
2L), digit = c(9L, 9L, 6L, 9L, 9L, 0L, 4L, 4L, 4L, 4L), timediff = c(0L,
9L, 17L, 17L, 8L, 8L, 200L, 17L, 17L, 8L)), .Names = c("label",
"digit", "timediff"), class = "data.frame", row.names = c(NA,
-10L))
那你可以试试tidyverse
d %>%
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit)
label digit timediff
1 1 9 0
2 1 9 9
3 1 4 17
4 1 6 17
5 1 0 8
6 2 9 17
7 2 9 8
8 2 4 200
9 2 4 17
10 2 4 8
然后交互使用:
d %>%
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit) %>%
unite(ID, label, digit, sep=".") %>%
mutate(ID=factor(ID, levels = unique(ID))) %>%
with(.,levels(ID))
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"
或者在基础 R
中简单地使用 order
d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
label digit timediff
1 1 9 0
2 1 9 9
8 1 4 17
3 1 6 17
6 1 0 8
4 2 9 17
5 2 9 8
7 2 4 200
9 2 4 17
10 2 4 8
然后
d1 <- d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
d1$combined_factor <- with(d1, interaction(label, digit))
d1$combined_factor <- factor(d1$combined_factor, levels = unique(d1$combined_factor))
levels(d1$combined_factor)
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"
作为你的功能你可以试试
foo <- function(df, Code) df[order(df$label, factor(df$digit, levels = Code)),]
foo(d, c(9,4,6,0))
不需要使用 interaction
部分。如果你需要它。之后使用 1) tidyr
的 unite
或 2) interaction
创建交互。另见 ?sort
:"The sort order for factors is the order of their levels"
。因此,您只需更改因子水平。
给定如下数据框:
label digit timediff
1 9 0
1 9 9
1 9 17
2 9 17
2 9 8
1 9 8
2 4 200
1 4 17
2 4 17
2 4 8
我正在尝试处理连续数字(这是 PIN 码分析)。 我的密码是 9460。
我想根据label和digit来分析timediff。 首先,我使用
创建了一个列df$combined_factor <- with(df, interaction(label, digit))
但现在我需要根据数字外观来调整因子水平。
请指教如何才能"tell" combined_factor
列级别按数字出现的顺序排列(9 然后 4 然后 6 和 0)?
我探讨了这个问题:
但在我的情况下,我有标签。
例如combined_factor
可以是:
1.9
2.4
...
我希望它按数字顺序排列:1.9, ... 1.4, ... 1.6 ... 1.0, ... 2.9, ... 2.4, ... 2.6, ... 2.0 ....
label_digit timediff
<fct> <dbl>
1 1.9 0
2 1.9 9
3 1.9 17
4 1.9 17
5 1.9 8
6 1.9 8
7 1.4 200
8 1.4 17
9 1.4 17
10 1.4 8
levels(df$label_digit)
[1] "1.0" "2.0" "1.4" "2.4" "1.6" "2.6" "1.9" "2.9"
预计:
levels(df$label_digit):
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4" "2.6" "2.0"
由于您提供的可重现数据不佳,我将使用自己的数据:
d <- structure(list(label = c(1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 2L,
2L), digit = c(9L, 9L, 6L, 9L, 9L, 0L, 4L, 4L, 4L, 4L), timediff = c(0L,
9L, 17L, 17L, 8L, 8L, 200L, 17L, 17L, 8L)), .Names = c("label",
"digit", "timediff"), class = "data.frame", row.names = c(NA,
-10L))
那你可以试试tidyverse
d %>%
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit)
label digit timediff
1 1 9 0
2 1 9 9
3 1 4 17
4 1 6 17
5 1 0 8
6 2 9 17
7 2 9 8
8 2 4 200
9 2 4 17
10 2 4 8
然后交互使用:
d %>%
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit) %>%
unite(ID, label, digit, sep=".") %>%
mutate(ID=factor(ID, levels = unique(ID))) %>%
with(.,levels(ID))
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"
或者在基础 R
中简单地使用 order
d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
label digit timediff
1 1 9 0
2 1 9 9
8 1 4 17
3 1 6 17
6 1 0 8
4 2 9 17
5 2 9 8
7 2 4 200
9 2 4 17
10 2 4 8
然后
d1 <- d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
d1$combined_factor <- with(d1, interaction(label, digit))
d1$combined_factor <- factor(d1$combined_factor, levels = unique(d1$combined_factor))
levels(d1$combined_factor)
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"
作为你的功能你可以试试
foo <- function(df, Code) df[order(df$label, factor(df$digit, levels = Code)),]
foo(d, c(9,4,6,0))
不需要使用 interaction
部分。如果你需要它。之后使用 1) tidyr
的 unite
或 2) interaction
创建交互。另见 ?sort
:"The sort order for factors is the order of their levels"
。因此,您只需更改因子水平。