我的一个数据框(df1)有一个这样的列:
ID
AB
CD;EF
IJ
KL
MN
OP;WX
WW
YZ
另一个数据框(df2)具有以下格式(这是一个非常大的数据表):
myIDColumn someName somevalue
AB gsdfg 123
CD tfgsdfg 234
EF sfdgsf 365
GH gdfgb 53453
IJ sr 64564
KL sfsdv 4234234
MN ewrwe 5
OP dsfsss 3453
QR gggg 667
ST dss 7567
UV hhhhjf 55
WX dfadasad 8657
YZ ghfgh 1234
ABC gdgfg 234455
VCB hgjkk 5555667
我想基于我的df1合并数据帧,但我该如何解决这个问题 这个特殊连接上的分号。有没有办法使用正则表达式连接这些数据帧?
我想要的输出:
ID someName somevalue AB gsdfg 123 CD;EF tfgsdfg,sfdgsf 234,365 IJ sr 64564 KL sfsdv 4234234 MN ewrwe 5 OP;WX dsfsss,dfadasad 3453,8657 WW YZ dfadasad 8657 TT
非常感谢任何帮助。谢谢!
答案 0 :(得分:4)
这是一个紧凑的解决方案。请注意,所有字段都将转换为字符,因为没有其他方法可以将两个整数存储在一个元素中。如果df1$ID
中的df2$miIDColumn
中缺少值"character(0)"
,那么您将获得IDs <- strsplit(df1$ID, ";")
mrg <- foreach(x=IDs, .combine=rbind) %do% {
pieces <- lapply(x, function(y) df2[df2$myIDColumn %in% y,])
do.call(paste, c(pieces, list(sep=",")))
}
dimnames(mrg) <- list(NULL, colnames(df2))
值。
mrg
这是输出( myIDColumn someName somevalue
[1,] "AB" "gsdfg" "123"
[2,] "CD,EF" "tfgsdfg,sfdgsf" "234,365"
[3,] "IJ" "sr" "64564"
[4,] "KL" "sfsdv" "4234234"
[5,] "MN" "ewrwe" "5"
[6,] "OP,WX" "dsfsss,dfadasad" "3453,8657"
[7,] "character(0)" "character(0)" "integer(0)"
[8,] "YZ" "ghfgh" "1234"
是矩阵btw):
{{1}}
答案 1 :(得分:4)
分2步,类似于发布的解决方案,但采用更紧凑的方式。
这里是代码:
##step1
mm <- merge(df2,df1,by.y='ID',by.x='myIDColumn',all.y=TRUE)
## step2
rr <- do.call(rbind,lapply(strsplit(mm$myIDColumn[grep(';',mm$myIDColumn)],';'),
function(x){
res <- paste(df2[df2$myIDColumn==x[1],],
df2[df2$myIDColumn==x[2],],
sep=',')
res[1] <- paste(x,collapse=';')
res}))
mm[grep(';',mm$myIDColumn),] <- rr
myIDColumn someName somevalue
1 AB gsdfg 123
2 CD;EF tfgsdfg,sfdgsf 234,365
3 IJ sr 64564
4 KL sfsdv 4234234
5 MN ewrwe 5
6 OP;WX dsfsss,dfadasad 3453,8657
7 WW <NA> <NA>
8 YZ ghfgh 1234
答案 2 :(得分:2)
这是一个策略,涉及将df1
分成两个新的数据框(一个是你正常合并到df2
的一种,一个是分号ID
的,这个很难处理)。
l <- grep(";",df1$ID) # semicolon lines
nl <- which(!grepl(";",df1$ID)) # non-semicolon lines
# merge non-semicolon lines
newdfA <- merge(df1[nl,],df2,all.x=TRUE)
# merge semicolon lines
tmpdf1 <- df1[l,]
split <- strsplit(tmpdf1$ID,";")
### This seems sloppy, but should work
newdfB <- data.frame(t(sapply(split, FUN=
function(x){
tmprows <- df2[df2$ID %in% x,]
return(c( paste0(tmprows[,1],collapse=";"),
paste0(tmprows[,2],collapse=","),
paste0(tmprows[,3],collapse=",") ))
} )))
colnames(newdfB) <- c("ID","someName","someValue")
# merge everything back together
newdf <- merge(newdfA, newdfB, all=TRUE)