【问题标题】:Extract data from one data frame to another data frame with different row length将数据从一个数据帧提取到另一个具有不同行长的数据帧
【发布时间】:2016-04-29 03:31:31
【问题描述】:

我有两个data.frames如下:

df1 <- data.frame(A=c("lee","eeu","ees"), B=c("lee","ggu","1su"), C=c(1,1,1)

    A   B C
1 lee lee 1
2 eeu ggu 1
3 ees 1su 1


df2 <- data.frame (X=c("lee","1su","eeu","ggu"), Y=c("3k3","4k4","5k","2ee"), Z=c("ggg","","","ooo"), ZA=c("vvv","","",""))

    X   Y   Z  ZA
1 lee 3k3 ggg vvv
2 1su 4k4        
3 eeu  5k        
4 ggu 2ee ooo    

我想通过将 df1$B 与 df2$X 匹配来扩展 df1。当 df1$B = df2$X 时,我想在 new_df1 中添加额外的行,新 B = df2 中的其他条目在同一行,但保持 A 和 C 相同。

new_df1 预计如下:

 A   B  C
lee 3k3 1 ### df1$B1= df2$X1= lee
lee ggg 1
lee vvv 1
eeu 2ee 1 ### df1$B2= df2$X4= ggu
eeu ooo 1
ees 4k4 1 ### df1$B3= df2$X2= lsu

我过去使用 lapply 的经验似乎非常需要内存,是否可以不使用 lapply 来完成?

【问题讨论】:

    标签: r match


    【解决方案1】:

    我认为你想要的是这个的一个子集:

    require(reshape2)
    merge(df1,melt(df2, id.var="X"), by.x="B", by.y="X", all=TRUE)
         B    A  C variable value
    1  1su  ees  1        Y   4k4
    2  1su  ees  1        Z      
    3  1su  ees  1       ZA      
    4  ggu  eeu  1        Y   2ee
    5  ggu  eeu  1        Z   ooo
    6  ggu  eeu  1       ZA      
    7  lee  lee  1        Y   3k3
    8  lee  lee  1        Z   ggg
    9  lee  lee  1       ZA   vvv
    10 eeu <NA> NA        Y    5k
    11 eeu <NA> NA        Z      
    12 eeu <NA> NA       ZA      
    

    我将该对象分配给“M1”(后来发现它不需要 all=TRUE)

    M1 <- merge(df1,melt(df2, id.var="X"), by.x="B", by.y="X")
    subset(M1, value != "" , select=c(A,value, C) )
        A value C
    1 ees   4k4 1
    4 eeu   2ee 1
    5 eeu   ooo 1
    7 lee   3k3 1
    8 lee   ggg 1
    9 lee   vvv 1
    

    【讨论】:

    • 但是您的 newdf 的行数比他要求的多。再次查看问题,我修改了答案,因此我不需要或不需要测试 NA。
    【解决方案2】:

    我会使用 reshape 包中的 melt() 来完成这项任务。

     melt(df2, c("X"))
         X variable value
    1  lee        Y   3k3
    2  1su        Y   4k4
    3  eeu        Y    5k
    4  ggu        Y   2ee
    5  lee        Z   ggg
    6  1su        Z      
    7  eeu        Z      
    8  ggu        Z   ooo
    9  lee       ZA   vvv
    10 1su       ZA      
    11 eeu       ZA      
    12 ggu       ZA      
    
    x <- melt(df2, c("X"))
    x$variable <- NULL
    x$C <- 1
    colnames(x) <- c("A","B","C")
    

    现在子集和 rbind()

    x <- subset(x, B != "")
    newdf <- rbind(df1, x)
    

    【讨论】:

      【解决方案3】:

      要做到这一点要容易得多...使用match 函数。

      df1$Y <- df2$Y[match(df1$B, df2$X)]
      

      您也可以将其扩展到其他列。

      【讨论】:

      • 我不明白您将如何使用它来添加额外的行。你能扩展你的答案吗?
      【解决方案4】:
      #example data.frames
      d <- data.frame(a=c(1:10), b=c(1:10))
      e <- data.frame(a=c(5:1), b=c(5:1))
      
      #add row number of reference data.frame
      d$row <- c(1:nrow(d))
      
      #merge data.frames by desired columns
      m<- merge.data.frame(d,e,by=c("a","b"))
      
      #check results
      m$row
      d$row %in% m$row
      

      【讨论】:

        最近更新 更多