R-合并两个数据帧,但某些值中包含半冒号

时间:2013-05-27 07:25:41

标签: r join merge dataframe

我的一个数据框(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

非常感谢任何帮助。谢谢!

3 个答案:

答案 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步,类似于发布的解决方案,但采用更紧凑的方式。

  1. 合并2 data.frame
  2. 然后转换包含“;”
  3. 的行

    这里是代码:

    ##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)