我有一个ID和地址的数据框。通常情况下,我希望每个重复ID在所有观察中都具有相同的地址,但我的一些ID具有不同的地址。我想找到那些在ID上重复的观察,但至少有2个不同的地址。然后,我想为其中一个随机化一个新ID(之前在DF中不存在的ID)。
例如:
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
将返回:
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
所发生的事情是第3次,第7次,第9次和第10次观察得到了新的ID。我将提到ID可能有超过2个不同的地址,因此每个唯一地址都应该为新ID授予权限。
编辑:
我为数据框的较长示例添加了一个代码,rand列应该被忽略但保留在最终输出中。
df <- data.frame(ID = c(1,1,1,2,2,3,3,4,4,4,5,5,5),
Address = c("x","x","y","z","z","a","b","c","d","e",
"f","f","f"),
rand = sample(1:100, 13))
答案 0 :(得分:4)
以下是tidyr
和函数nest
/ unnest
library(tidyr)
library(dplyr)
df %>% group_by(ID,Address) %>% nest %>%
`[<-`(duplicated(.$ID),"ID",max(.$ID, na.rm = TRUE) + 1:sum(duplicated(.$ID))) %>%
unnest
# # A tibble: 13 x 3
# ID Address rand
# <dbl> <fctr> <int>
# 1 1 x 58
# 2 1 x 4
# 3 6 y 75
# 4 2 z 5
# 5 2 z 19
# 6 3 a 55
# 7 7 b 34
# 8 4 c 53
# 9 8 d 98
# 10 9 e 97
# 11 5 f 13
# 12 5 f 64
# 13 5 f 80
如果您使用magrittr
,请将[<-
替换为inset
,如果您想要更漂亮的代码(相同的输出)。
答案 1 :(得分:2)
选项为data.table
。按“ID”分组后,if
unique
'地址'的数量大于1且'地址'不等于第一个unique
'地址',然后获取行索引(.I
)并将那些“ID”分配给原始数据集中尚未包含的“ID”
library(data.table)
i1 <- setDT(df)[, .I[if(uniqueN(Address)>1) Address != unique(Address)[1]], ID]$V1
df[i1, ID := head(setdiff(as.numeric(1:10), unique(df$ID)), length(i1))]
df
# ID Address rand
# 1: 1 x 58
# 2: 1 x 4
# 3: 6 y 75
# 4: 2 z 5
# 5: 2 z 19
# 6: 3 a 55
# 7: 7 b 34
# 8: 4 c 53
# 9: 8 d 98
# 10: 9 e 97
# 11: 5 f 13
# 12: 5 f 64
# 13: 5 f 80
或者我们可以使用base R
ids <- names(which(rowSums(table(unique(df)))>1))
i2 <- with(df, ID %in% ids & Address != ave(as.character(Address),
ID, FUN = function(x) x[1]))
df$ID[i2] <- head(setdiff(1:10, unique(df$ID)), sum(i2))