双匹配数据框中的两列

时间:2018-06-02 20:22:32

标签: r matching

library(data.table)
data <- setDT(data.frame(name=c(NA, "bob1", "bob", "jack", "bob1", "bob"), ID=c(1,1,4,3,2,1)))

     name   ID 
1:    NA     1    
2:    bob1   1    
3:    bob    4   
4:    jack   3
5:    bob1   2
6:    bob    1

匹配标准(同时):

  • 如果不同的名称具有相同的ID,请将名称更改为唯一的名称

  • 如果其他ID具有相同的名称,请将ID更改为唯一ID

期望的输出:

     name   ID 
1:    bob    1    
2:    bob    1    
3:    bob    1   
4:    jack   3
5:    bob    1
6:    bob    1

     name   ID 
1:    bob1   1    
2:    bob1   1    
3:    bob1   1   
4:    jack   3
5:    bob1   1
6:    bob1   1

2 个答案:

答案 0 :(得分:1)

您的问题没有明确定义,这里有两个满足您标准的解决方案,但它们都不是您想要的输出:

library(data.table)

data <- setDT(data.frame(name=c(NA, "bob1", "bob", "jack", "bob1", "bob"), ID=c(1,1,4,3,2,1)))    
data <- na.omit(data) # remove NAs
data$ID <- data$ID[match(data$name,data$name)] # harmonize ids
data$name <- data$name[match(data$ID,data$ID)] # harmonize names
data
#    name ID
# 1: bob1  1
# 2:  bob  4
# 3: jack  3
# 4: bob1  1
# 5:  bob  4


data <- setDT(data.frame(name=c(NA, "bob1", "bob", "jack", "bob1", "bob"), ID=c(1,1,4,3,2,1)))
data <- na.omit(data) # remove NAs
data$name <- data$name[match(data$ID,data$ID)] # harmonize names
data$ID <- data$ID[match(data$name,data$name)] # harmonize ids
data
#    name ID
# 1: bob1  1
# 2:  bob  4
# 3: jack  3
# 4: bob1  1
# 5: bob1  1

答案 1 :(得分:1)

一种选择是使用mapplyorderdata.table没有做任何特别的事情,因此我更喜欢使用data.frame

data <- data.frame(name=c(NA, "bob1", "bob", "jack", "bob1", "bob"), 
                   ID=c(1,1,4,3,2,1), stringsAsFactors =  FALSE)

# First order on ID
data[order(data$ID),]

as.data.frame(t(mapply(function(x,y){
  data[which(!is.na(data$name) & ((!is.na(y) & y==data$name) | x == data$ID))[1],]

}, data$ID, data$name)))

#   name ID
# 1 bob1  1
# 2 bob1  1
# 3 bob1  1
# 4 bob1  1
# 5 jack  3
# 6 bob1  1