如何在R中按顺序重新编号组id?
我正在尝试使用如何在R中按顺序重新编号组id?,r,dplyr,rename,tidyverse,R,Dplyr,Rename,Tidyverse,我正在尝试使用R中的dplyr按顺序重命名分组的唯一id。 数据框中有五列,如下所示 ## Load package if necessary library(tidyverse) ## Set data frame df <- data.frame( hid=c(10001,10001,10001,10001,10002,10002,10002,10002,10002, 10003,10003,10003,10003,10003,10003,10004,10
R
中的dplyr
按顺序重命名分组的唯一id。
数据框中有五列,如下所示
## Load package if necessary
library(tidyverse)
## Set data frame
df <- data.frame(
hid=c(10001,10001,10001,10001,10002,10002,10002,10002,10002,
10003,10003,10003,10003,10003,10003,10004,10004,10004,10004,10004),
mid=c(1,2,3,4,1,2,3,4,5,1,2,3,4,5,6,1,2,3,4,5),
tmc=c(010,01010,0,01020,010,010,010,010,010,010,010,010,0,010,010,010,0,01010,010,01010),
thc=c(010,01010,0,02030,010,020,020,020,030,010,010,010,0,020,030,010,0,02020,030,04040),
mdc=c(000,01010,0,02020,000,010,010,010,010,000,000,010,0,010,020,000,0,02020,010,01010),
itc=c(010,01010,0,02020,020,020,020,020,020,010,010,010,0,020,020,010,0,02020,020,02020)
)
由于它不提供顺序ID,我需要重命名它。
然而,我找不到解决办法。条件是:
- 如果
、tmc
、thc
和mdc
均为0,itc
设置为id
(我不知道原因,但0
交互
在我的数据框中给出了
)1
- 其他ID应按顺序重命名,但需要保留其组。(如果
s设置为id
,则应将其重命名为4,8,2,2,8
)1,2,3,3,2
id
是从interaction
函数中获取的临时id,但我需要获取id.required
列中指示的顺序id
## Replace unique id sequentially
## IT DOES NOT GIVE DESIRED OUTPUT
# df.id %>% group_by(id) %>% mutate(id2=seq_along(id))
## Desired id is shown in `id.desired`
## `id` is the ones obtained from `interaction` function, which are not set sequentially
hid mid tmc thc mdc itc id id.desired
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
1 10001 1 10 10 0 10 166 1
2 10001 2 1010 1010 1010 1010 595 2
3 10001 3 0 0 0 0 1 0
4 10001 4 1020 2030 2020 2020 796 3
5 10002 1 10 10 0 20 326 4
6 10002 2 10 20 10 20 362 5
7 10002 3 10 20 10 20 362 5
8 10002 4 10 20 10 20 362 5
9 10002 5 10 30 10 20 366 6
10 10003 1 10 10 0 10 166 1
11 10003 2 10 10 0 10 166 1
12 10003 3 10 10 10 10 198 7
13 10003 4 0 0 0 0 1 0
14 10003 5 10 20 10 20 362 5
15 10003 6 10 30 20 20 398 8
16 10004 1 10 10 0 10 166 1
17 10004 2 0 0 0 0 1 0
18 1004 3 1010 2020 2020 2020 791 9
19 10004 4 10 30 10 20 366 6
20 10004 5 1010 4040 1010 2020 767 10
##按顺序替换唯一id
##它不能提供所需的输出
#df.id%>%group_by(id)%>%mutate(id2=seq_沿(id))
##所需id显示在'id.required'中`
##`id`是从`interaction`函数获得的,不是按顺序设置的
需要hid mid tmc thc mdc itc id
1 10001 1 10 10 0 10 166 1
2 10001 2 1010 1010 1010 1010 595 2
3 10001 3 0 0 0 0 1 0
4 10001 4 1020 2030 2020 2020 796 3
5 10002 1 10 10 0 20 326 4
6 10002 2 10 20 10 20 362 5
7 10002 3 10 20 10 20 362 5
8 10002 4 10 20 10 20 362 5
9 10002 5 10 30 10 20 366 6
10 10003 1 10 10 0 10 166 1
11 10003 2 10 10 0 10 166 1
12 10003 3 10 10 10 10 198 7
13 10003 4 0 0 0 0 1 0
14 10003 5 10 20 10 20 362 5
15 10003 6 10 30 20 20 398 8
16 10004 1 10 10 0 10 166 1
17 10004 2 0 0 0 0 1 0
18 1004 3 1010 2020 2020 2020 791 9
19 10004 4 10 30 10 20 366 6
20 10004 5 1010 4040 1010 2020 767 10
有什么建议吗?
我更喜欢在这个操作中使用dplyr
我在上一个问题中收到了一些建议,但是在本例中它的结构不同(dummy
字段在当前数据帧中不存在)。
不确定如何解释
id.desired
列,但下面是一个基于两个条件并使用data.table的示例:
require(data.table)
df = data.table(df)
df[tmc != 0 & thc != 0 & mdc != 0 & itc != 0, ID := 1:.N, by = .(tmc, thc, mdc, itc)]
df[is.na(ID), ID := 0]
(根据您在评论中的澄清进行修改)以下是我尝试做的两件事:
id.desired
,我使用了稠密的_rank()函数李>
以下是基于您共享的数据集的代码:
df %>%
mutate(id = if_else(tmc == 0 & thc == 0 & mdc == 0 & itc == 0, 0,
as.numeric(interaction(tmc, thc, mdc, itc, lex.order = TRUE)))) %>%
mutate(id.desired = dense_rank(id) - 1)
输出如下所示
hid mid tmc thc mdc itc id id.desired
1 10001 1 10 10 0 10 227 1
2 10001 2 1010 1010 1010 1010 519 7
3 10001 3 0 0 0 0 0 0
4 10001 4 1020 2030 2020 2020 775 10
5 10002 1 10 10 0 20 228 2
6 10002 2 10 20 10 20 258 4
7 10002 3 10 20 10 20 258 4
8 10002 4 10 20 10 20 258 4
9 10002 5 10 30 10 20 283 5
10 10003 1 10 10 0 10 227 1
11 10003 2 10 10 0 10 227 1
12 10003 3 10 10 10 10 232 3
13 10003 4 0 0 0 0 0 0
14 10003 5 10 20 10 20 258 4
15 10003 6 10 30 20 20 288 6
16 10004 1 10 10 0 10 227 1
17 10004 2 0 0 0 0 0 0
18 10004 3 1010 2020 2020 2020 550 8
19 10004 4 10 30 10 20 283 5
20 10004 5 1010 4040 1010 2020 595 9
使用
tidyverse
的解决方案。请注意,我没有使用交互
函数。相反,我使用dplyr
中的group\u index
函数来创建组索引,然后根据列中的出现顺序转换为因子并更改级别df2
是最终输出
library(tidyverse)
df2 <- df %>%
filter_at(vars(tmc, thc, mdc, itc), any_vars(. != 0)) %>%
mutate(id = group_indices(., tmc, thc, mdc, itc)) %>%
mutate(id = as.numeric(factor(id, levels = unique(id)))) %>%
left_join(df, ., by = names(df)) %>%
replace_na(list(id = 0))
df2
# hid mid tmc thc mdc itc id
# 1 10001 1 10 10 0 10 1
# 2 10001 2 1010 1010 1010 1010 2
# 3 10001 3 0 0 0 0 0
# 4 10001 4 1020 2030 2020 2020 3
# 5 10002 1 10 10 0 20 4
# 6 10002 2 10 20 10 20 5
# 7 10002 3 10 20 10 20 5
# 8 10002 4 10 20 10 20 5
# 9 10002 5 10 30 10 20 6
# 10 10003 1 10 10 0 10 1
# 11 10003 2 10 10 0 10 1
# 12 10003 3 10 10 10 10 7
# 13 10003 4 0 0 0 0 0
# 14 10003 5 10 20 10 20 5
# 15 10003 6 10 30 20 20 8
# 16 10004 1 10 10 0 10 1
# 17 10004 2 0 0 0 0 0
# 18 10004 3 1010 2020 2020 2020 9
# 19 10004 4 10 30 10 20 6
# 20 10004 5 1010 4040 1010 2020 10
库(tidyverse)
df2%
过滤器位于(变量(tmc、thc、mdc、itc),任何变量(.!=0))%>%
突变(id=组_指数(、tmc、thc、mdc、itc))%>%
变异(id=as.numeric(factor(id,levels=unique(id)))%>%
左联合(df,by=names(df))%>%
替换(列表(id=0))
df2
#hid mid tmc thc mdc itc id
# 1 10001 1 10 10 0 10 1
# 2 10001 2 1010 1010 1010 1010 2
# 3 10001 3 0 0 0 0 0
# 4 10001 4 1020 2030 2020 2020 3
# 5 10002 1 10 10 0 20 4
# 6 10002 2 10 20 10 20 5
# 7 10002 3 10 20 10 20 5
# 8 10002 4 10 20 10 20 5
# 9 10002 5 10 30 10 20 6
# 10 10003 1 10 10 0 10 1
# 11 10003 2 10 10 0 10 1
# 12 10003 3 10 10 10 10 7
# 13 10003 4 0 0 0 0 0
# 14 10003 5 10 20 10 20 5
# 15 10003 6 10 30 20 20 8
# 16 10004 1 10 10 0 10 1
# 17 10004 2 0 0 0 0 0
# 18 10004 3 1010 2020 2020 2020 9
# 19 10004 4 10 30 10 20 6
# 20 10004 5 1010 4040 1010 2020 10
谢谢!这看起来不错,但我需要一些更新,如果可能的话:1。对不起,我的解释错了:我需要所有零记录的0
,而不是1
。2.我更喜欢有顺序的id.required
,以便轻松理解唯一id的分布。我的意思是id.desired
应该从零开始,除了所有值为0
的零记录。3. dense_rank
函数很好,但它似乎没有满足我评论中的第二点(它不返回序列号)。它还可以将0
重命名为其他值,该值被赋予所有零
记录。对不起,我不能断线…如果你从id.desired
中减去1,这能实现你的目标吗dense_rank
已经根据id
变量的数字顺序给出了顺序排列,因此顺序问题也应该得到解决……或者我误解了您的要求?我已经根据您提供的说明对答案进行了编辑。如果您想按升序排列id.desired
,您可以在代码末尾添加%>%arrange(id.desired)
。感谢您的更新,但是更新了id.desired
7,0,10,2,4,4,4,4,4,5,1,1,3,0,8,5,9
应该是1,0,2,3,4,4,5,6,6,7,0,4,8,6,5,10<代码>id。所需的
应从library(tidyverse)
df2 <- df %>%
filter_at(vars(tmc, thc, mdc, itc), any_vars(. != 0)) %>%
mutate(id = group_indices(., tmc, thc, mdc, itc)) %>%
mutate(id = as.numeric(factor(id, levels = unique(id)))) %>%
left_join(df, ., by = names(df)) %>%
replace_na(list(id = 0))
df2
# hid mid tmc thc mdc itc id
# 1 10001 1 10 10 0 10 1
# 2 10001 2 1010 1010 1010 1010 2
# 3 10001 3 0 0 0 0 0
# 4 10001 4 1020 2030 2020 2020 3
# 5 10002 1 10 10 0 20 4
# 6 10002 2 10 20 10 20 5
# 7 10002 3 10 20 10 20 5
# 8 10002 4 10 20 10 20 5
# 9 10002 5 10 30 10 20 6
# 10 10003 1 10 10 0 10 1
# 11 10003 2 10 10 0 10 1
# 12 10003 3 10 10 10 10 7
# 13 10003 4 0 0 0 0 0
# 14 10003 5 10 20 10 20 5
# 15 10003 6 10 30 20 20 8
# 16 10004 1 10 10 0 10 1
# 17 10004 2 0 0 0 0 0
# 18 10004 3 1010 2020 2020 2020 9
# 19 10004 4 10 30 10 20 6
# 20 10004 5 1010 4040 1010 2020 10