在尝试解决这个问题的同时Identify duplicates of one value with different values in another column;我觉得解决方案更接近,但我不能,因为dplyr mutate
函数在我在下面的代码中使用max
而不是后突变值时引用了预变异状态max(ID)
(像递归一样)。
目标是为当前地址与相同ID值的先前地址不匹配的行分配新的唯一ID值。
我试过的代码:
df <- read.table(text = 'ID Address
1 X
1 X
1 Y
2 Z
2 Z
3 A
3 B
4 C
4 D
4 E
5 F
5 F
5 F
', header= T, stringsAsFactors = F)
df %>% group_by(ID) %>% mutate(flag = ifelse(lag(Address)==Address,F,T)) %>%
mutate(flag = ifelse(is.na(flag),F,flag)) %>% ungroup() %>%
mutate(newID = ifelse(flag | is.na(flag), max(ID)+1,ID))%>%
select(ID = newID,Address)
收到的输出:
# A tibble: 13 x 2
ID Address
<dbl> <chr>
1 1 X
2 1 X
3 6 Y
4 2 Z
5 2 Z
6 3 A
7 6 B
8 4 C
9 6 D
10 6 E
11 5 F
12 5 F
13 5 F
预期产出:
ID Address
1 X
1 X
6 Y
2 Z
2 Z
3 A
7 B
4 C
8 D
9 E
5 F
5 F
5 F
任何帮助将不胜感激!
编辑:
理想代码:我应该能够使用newID
,这是当前使用的变异变量。
> df %>% group_by(ID) %>% mutate(flag = ifelse(lag(Address)==Address,F,T)) %>%
+ mutate(flag = ifelse(is.na(flag),F,flag)) %>% ungroup() %>%
+ mutate(newID = ifelse(flag | is.na(flag), max(newID)+1,ID))%>%
+ select(ID = newID,Address)
答案 0 :(得分:2)
一个问题是max(ID) + 1
将给出常数值,第二个问题是ifelse
本身需要相等长度的向量才能得到&#39;是&#39;并且没有&#39;。在下面的解决方案中,我们将max(ID) + 1
替换为max(ID) + seq_len(sum(flag))
而不是ifelse
使用replace
df %>%
group_by(ID) %>%
mutate(flag = lag(Address, default = Address[1])!= Address) %>%
ungroup() %>%
mutate(newID = replace(ID, flag, max(ID) + seq_len(sum(flag))))%>%
select(ID = newID,Address)
# A tibble: 13 x 2
# ID Address
# <dbl> <chr>
# 1 1 X
# 2 1 X
# 3 6 Y
# 4 2 Z
# 5 2 Z
# 6 3 A
# 7 7 B
# 8 4 C
# 9 8 D
#10 9 E
#11 5 F
#12 5 F
#13 5 F
此外,两个ifelse
语句用于创建“标记”标记。可以用单个语句替换