假设我有两个数据帧,df1
和df2
。两个数据帧都具有标识符CCD_ 3。我的目标是合并这个标识符上的那些数据集,但我想匿名id
列中的名称。然而,问题是,我想分别对两个数据集这样做,因此对df1
和df2
这样做,而不是直接对df3
这样做(因为这很容易:只需用一些随机字符替换id
列(
我想我的解决方案应该是这样的。首先,我制作了一个单独的数据帧,由来自df1
和df2
的所有唯一的id
组成。然后,我需要分配一些随机化,例如idxxxx
,其中xxxx
是该单独数据帧中每个id
的唯一编号。使用dplyr
、gsub
或stringr
方法,我可以根据在该单独数据帧中分配的值来替换df1
和df2
中的id
s。之后,我将合并这两个数据集。
这里我有两个示例数据帧,我试图解决问题,以及期望的结果。请注意,id的数量对我来说并不重要(例如,John Terry是否有id0004或id0003并不重要,只要它在两个数据帧内都一致更改即可。
有人能帮我吗?谢谢
id <- c("John Williams", "John Terry", "Rick Fire", "Katie Blue", "Unknown")
row1 <- c("28", "17", "17", "29", "39")
df1 <- data.frame(id,row1)
id <- c("Frank Johnson", "John Terry", "Rick Fire", "Katie Blue")
row2 <- c("Purple", "Red", "Yellow", "Green")
df2 <- data.frame(id,row2)
df3 <- merge(df1, df2, all.x = TRUE, all.y = TRUE)
#My try
#Make separate data frame
id_df <- merge(df1, df2, all.x = TRUE, all.y = TRUE)
id_df <- subset(id_df,TRUE,select = c(id))
id_df$anonymous <- id_df %>% mutate(id = row_number()) #it would be nicer to have something like id0001
#Replace ids within df1 and df2 according to the id_df anonymous variable
library(stringr)
df1$id <- str_replace(df1$id, id_df$id, as.character(id_df$anonymous)) #replacement does not work
#desired result
#df1 row1
#id0003 28
#id0002 17
#id0005 17
#id0004 29
#id0006 39
#df2 row2
#id0001 Purple
#id0002 Red
#id0005 Yellow
#id0004 Green
#df3
#id #row1 #row2
#id0001 NA Purple
#id0002 17 Red
#id0003 28 NA
#id0004 29 Green
#id0005 17 Yellow
#id0006 39 NA
如果你想匿名化id并使其反向变得相当困难,你可以计算每个字符串的md5哈希。两个相同的字符串将产生相同的md5散列:
df1$id <- sapply(df1$id, digest::digest, algo = "md5")
df2$id <- sapply(df2$id, digest::digest, algo = "md5")
df3 <- merge(df1, df2, all.x = TRUE, all.y = TRUE)
df3
#> id row1 row2
#> 1 22e35044ed452870ad5b014e87121d9d 39 <NA>
#> 2 69d61b42a2f549c4765699f06de3b351 28 <NA>
#> 3 ad1cc76e26c5d73ba4a03bf51df1b6af 17 Yellow
#> 4 b3bdcc4913da319308e6ddf47e09da12 <NA> Purple
#> 5 badea53ae1e8a2fa66ebd1cdde9dd413 17 Red
#> 6 d1f305c19a2f9649abe11efcf26ac645 29 Green
这里有一个所有基为R(没有tidyverse(的解决方案。我们创建了一个具有所有唯一ID的查找表(使用设置操作union
来查找ID(,然后分别使用每个数据帧创建查找表merge
。
# Find all unique ids and create a lookup table.
all_ids <- union(df1$id, df2$id)
id_df <- data.frame(id = all_ids, code = paste0('id', sprintf('%04d', 1:length(all_ids))))
# Merge df1 with the lookup table, remove the id column, and rename the code column to id.
df1 <- merge(df1, id_df, all.x = TRUE)
df1 <- df1[, c('code', 'row1')]
names(df1)[1] <- 'id'
# Repeat for df2
df2 <- merge(df2, id_df, all.x = TRUE)
df2 <- df2[, c('code', 'row2')]
names(df2)[1] <- 'id'
df3 <- merge(df1, df2, all.x = TRUE, all.y = TRUE)
注意sprintf('%04d
,…(`将用零填充数字代码,总长度为4。
一个小型解决方案,满足您在加入之前不在df3
上操作的请求
id_df <- data.frame(id = union(df1$id,df2$id))
id_df <-
id_df %>%
mutate(anonymous = paste0("id", stringr::str_pad(row_number(),
width = 4,
pad = 0)))
newdf1 <- left_join(df1, id_df) %>% select(-id) %>% relocate(anonymous)
newdf2 <- left_join(df2, id_df) %>% select(-id) %>% relocate(anonymous)
full_join(newdf1, newdf2)
#> Joining, by = "anonymous"
#> anonymous row1 row2
#> 1 id0001 28 <NA>
#> 2 id0002 17 Red
#> 3 id0003 17 Yellow
#> 4 id0004 29 Green
#> 5 id0005 39 <NA>
#> 6 id0006 <NA> Purple