根据 R 中另一个变量的平均值重命名分类变量
Rename categorical variable according mean of another variable in R
我想根据另一个连续变量的值重命名一个分类变量。
set.seed(123)
temp <- data.frame(label = as.factor(c(rep(1,5),rep(2,5))),
number = c(runif(5, min =5, max = 12), runif(5,min = 3,max = 8)) ) %>% tibble()
>temp
label number
<fct> <dbl>
1 1 7.01
2 1 10.5
3 1 7.86
4 1 11.2
5 1 11.6
6 2 3.23
7 2 5.64
8 2 7.46
9 2 5.76
10 2 5.28
temp_update <- temp %>% group_by(label) %>%
mutate(mean_numb = mean(number)) %>% arrange(mean_numb) %>%
mutate(mean_numb=as.factor(round(mean_numb,2)))
> temp_update
# A tibble: 10 x 3
# Groups: label [2]
label number mean_numb
<fct> <dbl> <fct>
1 2 3.23 5.47
2 2 5.64 5.47
3 2 7.46 5.47
4 2 5.76 5.47
5 2 5.28 5.47
6 1 7.01 9.63
7 1 10.5 9.63
8 1 7.86 9.63
9 1 11.2 9.63
10 1 11.6 9.63
在这个小例子中,因为组2的mean(number)
小于组1的mean(number)
,我想将label == 1
重命名为2, label == 2
到 1.
这个例子只是我问题的一个小玩具,想象一下我可以有一个巨大数量的标签。
非常感谢
比我确定的可能要长一些,但这应该可以让您到达那里:
我们首先汇总数据,只从 mean(number)
中获取唯一值,然后使用 rank()
函数找出哪些较大。
然后我们使用 full_join()
将此信息与原始数据放回一起并与 label
列合并。
temp_update <- temp %>%
group_by(label) %>%
summarise(mean_numb = mean(number)) %>%
mutate(rank = rank(mean_numb)) %>%
full_join(temp, by="label") %>%
arrange(rank)
您可以确保列的名称现在最终替换了原来的 label
列,使用:
temp_update %>%
mutate(label = rank,
rank = NULL)
对于每个 label
,根据它们的平均值计算 mean
number
和 arrange
数据。然后您可以创建一个新的标签列 (new_label
),它只是根据平均值的行号。将此数据与原始数据连接起来以恢复所有行。
library(dplyr)
temp %>%
group_by(label) %>%
summarise(mean_num = mean(number)) %>%
arrange(mean_num) %>%
mutate(new_label = row_number()) %>%
inner_join(temp, by = 'label')
# label mean_num new_label number
# <fct> <dbl> <int> <dbl>
# 1 2 5.47 1 3.23
# 2 2 5.47 1 5.64
# 3 2 5.47 1 7.46
# 4 2 5.47 1 5.76
# 5 2 5.47 1 5.28
# 6 1 9.63 2 7.01
# 7 1 9.63 2 10.5
# 8 1 9.63 2 7.86
# 9 1 9.63 2 11.2
#10 1 9.63 2 11.6
为了比较,我在最终输出中同时保留了 label
和 new_label
列。如果不再需要,您可以使用 %>% select(-label)
删除 label
列。
为了完整起见,这里是使用 data.table
和 frank
函数的相同方法(您可能需要调整关系的排名方法,具体取决于您希望如何对两个组进行排名和标记均值相同):
library(data.table)
setDT(temp)
setkey(temp[temp[, .(mean_numb=mean(number)), by=label][, new_label:=frank(mean_numb)],
on="label"], new_label)[]
#> label number mean_numb new_label
#> 1: 2 3.227782 5.474131 1
#> 2: 2 5.640527 5.474131 1
#> 3: 2 7.462095 5.474131 1
#> 4: 2 5.757175 5.474131 1
#> 5: 2 5.283074 5.474131 1
#> 6: 1 7.013043 9.631682 2
#> 7: 1 10.518136 9.631682 2
#> 8: 1 7.862838 9.631682 2
#> 9: 1 11.181122 9.631682 2
#> 10: 1 11.583271 9.631682 2
我想根据另一个连续变量的值重命名一个分类变量。
set.seed(123)
temp <- data.frame(label = as.factor(c(rep(1,5),rep(2,5))),
number = c(runif(5, min =5, max = 12), runif(5,min = 3,max = 8)) ) %>% tibble()
>temp
label number
<fct> <dbl>
1 1 7.01
2 1 10.5
3 1 7.86
4 1 11.2
5 1 11.6
6 2 3.23
7 2 5.64
8 2 7.46
9 2 5.76
10 2 5.28
temp_update <- temp %>% group_by(label) %>%
mutate(mean_numb = mean(number)) %>% arrange(mean_numb) %>%
mutate(mean_numb=as.factor(round(mean_numb,2)))
> temp_update
# A tibble: 10 x 3
# Groups: label [2]
label number mean_numb
<fct> <dbl> <fct>
1 2 3.23 5.47
2 2 5.64 5.47
3 2 7.46 5.47
4 2 5.76 5.47
5 2 5.28 5.47
6 1 7.01 9.63
7 1 10.5 9.63
8 1 7.86 9.63
9 1 11.2 9.63
10 1 11.6 9.63
在这个小例子中,因为组2的mean(number)
小于组1的mean(number)
,我想将label == 1
重命名为2, label == 2
到 1.
这个例子只是我问题的一个小玩具,想象一下我可以有一个巨大数量的标签。
非常感谢
比我确定的可能要长一些,但这应该可以让您到达那里:
我们首先汇总数据,只从 mean(number)
中获取唯一值,然后使用 rank()
函数找出哪些较大。
然后我们使用 full_join()
将此信息与原始数据放回一起并与 label
列合并。
temp_update <- temp %>%
group_by(label) %>%
summarise(mean_numb = mean(number)) %>%
mutate(rank = rank(mean_numb)) %>%
full_join(temp, by="label") %>%
arrange(rank)
您可以确保列的名称现在最终替换了原来的 label
列,使用:
temp_update %>%
mutate(label = rank,
rank = NULL)
对于每个 label
,根据它们的平均值计算 mean
number
和 arrange
数据。然后您可以创建一个新的标签列 (new_label
),它只是根据平均值的行号。将此数据与原始数据连接起来以恢复所有行。
library(dplyr)
temp %>%
group_by(label) %>%
summarise(mean_num = mean(number)) %>%
arrange(mean_num) %>%
mutate(new_label = row_number()) %>%
inner_join(temp, by = 'label')
# label mean_num new_label number
# <fct> <dbl> <int> <dbl>
# 1 2 5.47 1 3.23
# 2 2 5.47 1 5.64
# 3 2 5.47 1 7.46
# 4 2 5.47 1 5.76
# 5 2 5.47 1 5.28
# 6 1 9.63 2 7.01
# 7 1 9.63 2 10.5
# 8 1 9.63 2 7.86
# 9 1 9.63 2 11.2
#10 1 9.63 2 11.6
为了比较,我在最终输出中同时保留了 label
和 new_label
列。如果不再需要,您可以使用 %>% select(-label)
删除 label
列。
为了完整起见,这里是使用 data.table
和 frank
函数的相同方法(您可能需要调整关系的排名方法,具体取决于您希望如何对两个组进行排名和标记均值相同):
library(data.table)
setDT(temp)
setkey(temp[temp[, .(mean_numb=mean(number)), by=label][, new_label:=frank(mean_numb)],
on="label"], new_label)[]
#> label number mean_numb new_label
#> 1: 2 3.227782 5.474131 1
#> 2: 2 5.640527 5.474131 1
#> 3: 2 7.462095 5.474131 1
#> 4: 2 5.757175 5.474131 1
#> 5: 2 5.283074 5.474131 1
#> 6: 1 7.013043 9.631682 2
#> 7: 1 10.518136 9.631682 2
#> 8: 1 7.862838 9.631682 2
#> 9: 1 11.181122 9.631682 2
#> 10: 1 11.583271 9.631682 2