R 联接中的通配符
这可能是一个愚蠢的想法,但无论如何让我问一下 我面临以下问题。我想在DT B上加入DT AR 联接中的通配符,r,data.table,R,Data.table,这可能是一个愚蠢的想法,但无论如何让我问一下 我面临以下问题。我想在DT B上加入DT A A<-data.table(a=c(1,2,3), b=c(4,5,6), key="a,b") B<-data.table(a=c(NA, 3, 3), b=c(6, NA, 6), c=c(5,6,7), key="a,b") B[A, mult="first"] a b c 1: 1 4 NA 2: 2 5 NA 3: 3 6 7 这是因为B的第二行“接受”表A中B列的所
A<-data.table(a=c(1,2,3), b=c(4,5,6), key="a,b")
B<-data.table(a=c(NA, 3, 3), b=c(6, NA, 6), c=c(5,6,7), key="a,b")
B[A, mult="first"]
a b c
1: 1 4 NA
2: 2 5 NA
3: 3 6 7
这是因为B的第二行“接受”表A中B列的所有值
有没有一个很好的方法来获得想要的结果
编辑:
在对这个问题思考了很长一段时间后,没有一个令人满意的结果,我会很感激一些想法。为此,让我解释一下比上面更广泛的情况:
我想把人们分成几个小组。一个人应该被划分为满足其要求的第一组。并非所有群体都要求一个人具有相同的属性。当该组对某一特征没有要求时,允许使用所有值
任何建议(不必涉及数据表)都将不胜感激
edit2:
我最终像这样解决了它,包括通配符支持,请随时为我指出改进
classification<-list(
list(
list("Michael", "Thomas"), list("Brown"), list("*"), list("A")
),
list(
list("*"), list("Red"), list(15, 16, 17, 18), list("B")
),
list(
list("Theresa"), list("Red"), list("*"), list("C")
),
list(
list("*"), list("Blond"), list("*"), list("D")
),
list(
list("*"), list("*"), list("*"), list("E")
)
)
participants<-data.table(name=c("Thomas", "Michael", "Sebastian", "Theresa", "Phil"),
hair=c("Brown", "Blond", "Black", "Red", "Grey"),
age=c(15, 25, 15, 16, 15))
configToMappingTable<-function(config, dt){
for(col in 1:(length(config[[1]])-1)){
colVal<-unique(unlist(dt[, col, with=F]));
for(row in 1:length(config)){
config[[row]][[col]]<-lapply(config[[row]][[col]], glob2rx);
config[[row]][[col]]<-unlist(lapply(config[[row]][[col]], function(x) as.list(colVal[grep(x, colVal)])), recursive=F);
}
}
res<-rbindlist(lapply(config, function(x) do.call(CJ, x)));
res<-res[, lapply(.SD, as.character)];
return(res[!duplicated(res[, 1:(ncol(res)-1), with=F])]);
}
mapping<-configToMappingTable(classification, participants)
setnames(mapping, c("name", "hair", "age", "group"))
mapping[, age:=as.numeric(age)]
setkey(participants, name, hair, age);
setkey(mapping, name, hair, age);
participants[mapping, group:=i.group]
classification您的意思是,如果您有一个多列键,当第二列为NA值时,您希望只在第一列上联接?是的,反之亦然(如果第二列为空,则仅在第一列上联接)。但不应仅限于2个键列。也许setkey(B,a)[a,mult='first'][,B:=i.B][,i.B:=NULL]
用所有可能的值填写NA(生成一个较大的表),然后进行常规联接
classification<-list(
list(
list("Michael", "Thomas"), list("Brown"), list("*"), list("A")
),
list(
list("*"), list("Red"), list(15, 16, 17, 18), list("B")
),
list(
list("Theresa"), list("Red"), list("*"), list("C")
),
list(
list("*"), list("Blond"), list("*"), list("D")
),
list(
list("*"), list("*"), list("*"), list("E")
)
)
participants<-data.table(name=c("Thomas", "Michael", "Sebastian", "Theresa", "Phil"),
hair=c("Brown", "Blond", "Black", "Red", "Grey"),
age=c(15, 25, 15, 16, 15))
configToMappingTable<-function(config, dt){
for(col in 1:(length(config[[1]])-1)){
colVal<-unique(unlist(dt[, col, with=F]));
for(row in 1:length(config)){
config[[row]][[col]]<-lapply(config[[row]][[col]], glob2rx);
config[[row]][[col]]<-unlist(lapply(config[[row]][[col]], function(x) as.list(colVal[grep(x, colVal)])), recursive=F);
}
}
res<-rbindlist(lapply(config, function(x) do.call(CJ, x)));
res<-res[, lapply(.SD, as.character)];
return(res[!duplicated(res[, 1:(ncol(res)-1), with=F])]);
}
mapping<-configToMappingTable(classification, participants)
setnames(mapping, c("name", "hair", "age", "group"))
mapping[, age:=as.numeric(age)]
setkey(participants, name, hair, age);
setkey(mapping, name, hair, age);
participants[mapping, group:=i.group]