【问题标题】:Filling in a data set using three "puzzle pieces"使用三个“拼图”填充数据集
【发布时间】:2012-04-03 23:07:50
【问题描述】:

我有三个数据框,第一个(带有列标题,但没有行编号)看起来像

ID    1   2   3
 A   12  NA  NA
 B   NA   7  NA
 C   NA  NA  22

第二个可能看起来像

ID    1   2   3
 A   NA   6  NA
 B   NA  NA  29
 C   43  NA  NA

最后,第三个看起来像

ID    1   2   3
 A   NA  NA  32
 B    5  NA  NA
 C   NA   2  NA  

第一列是 ID 列,对于所有三个数据框都是相同的。最后三列代表相同的变量(1、2 和 3)。观察 A 的记录,变量 1 仅在其中一个数据集中。观测值 A 的记录也是如此,变量 2,但它位于不同的数据集中。

如何将这些数据集合并在一起以获得类似的东西

ID    1   2   3
 A   12   6  32
 B    5   7  29
 C   43   2  22

抱歉,我没有更好的方式来描述这个问题。如果有人可以分享它的术语,那就太好了。

【问题讨论】:

    标签: r


    【解决方案1】:

    I didn't come up with it 但是:

    merge.new<-function(...,col.ID){
        inter<-merge(...)
        inter<-inter[order(inter[col.ID]),] #merged data sorted by ID
    
        #total columns and rows for the target dataframe
        total.row<-length(unique(inter[[col.ID]]))
        total.col<-dim(inter)[2]
        row.ID<-unique(inter[[col.ID]])
        target<-matrix(NA,total.row,total.col)
        target<-as.data.frame(target)
        names(target)<-names(inter)
    
        for (i in 1:total.row){
            inter.part<-inter[inter[col.ID]==row.ID[i],] #select all rows with the same ID
            for (j in 1:total.col){
                if (is.na(inter.part[1,j])){
                    if(is.na(inter.part[2,j])) {target[i,j]=NA}
                    else {target[i,j]=inter.part[2,j]}
                }
                else {target[i,j]=inter.part[1,j]}
    
            }
        }
    print(paste("total rows=",total.row))
    print(paste("total columns=",total.col))
    return(target)
    }
    

    如果您的数据被命名为一、二和三:

    > one
      ID  1  2  3
    2  A 12 NA NA
    3  B NA  7 NA
    4  C NA NA 22
    > two
      ID  1  2  3
    2  A NA  6 NA
    3  B NA NA 29
    4  C 43 NA NA
    > three
      ID  1  2  3
    2  A NA NA 32
    3  B  5 NA NA
    4  C NA  2 NA
    > merge.new(merge.new(one, two, all=TRUE, col.ID=1), three, all=TRUE, col.ID=1)
    [1] "total rows= 3"
    [1] "total columns= 4"
    [1] "total rows= 3"
    [1] "total columns= 4"
      ID  1 2  3
    1  A 12 6 32
    2  B  5 7 29
    3  C 43 2 22
    > 
    

    【讨论】:

      【解决方案2】:

      我不确定你是否可以直接用数据框做这件事,但如果不能,首先将它们转换为矩阵很容易:

      x <- matrix(c(12,NA,NA,NA,7,NA,NA,NA,22),3,3)
      y <- matrix(c(NA,NA,43,6,NA,NA,NA,29,NA),3,3)
      z <- matrix(c(NA,5,NA,NA,NA,2,32,NA,NA),3,3)
      b <- matrix(0,3,3)
      b[!is.na(x)] <- x[!is.na(x)]
      b[!is.na(y)] <- y[!is.na(y)]
      b[!is.na(z)] <- z[!is.na(z)]
      b
           [,1] [,2] [,3]
      [1,]   12    6   32
      [2,]    5    7   29
      [3,]   43    2   22
      

      【讨论】:

        【解决方案3】:

        标题不错!这和R - Vector/ Array Addition很像

        您可以将数据转换为多维数组,然后对“拼图”维度求和或取平均值:

        df1 <- read.table(text="ID    1   2   3
        A   12  NA  NA
        B   NA   7  NA
        C   NA  NA  22", header = TRUE)
        
        df2 <- read.table(text="ID    1   2   3
        A   NA   6  NA
        B   NA  NA  29
        C   43  NA  NA", header = TRUE)
        
        df3 <- read.table(text="ID    1   2   3
        A   NA  NA  32
        B    5  NA  NA
        C   NA   2  NA", header = TRUE)
        
        # gather inputs and remove common ID column
        lists  <- list(df1, df2, df3)
        pieces <- lapply(lists, '[', , -1)
        
        # turn data into a multi-dimensional array
        a <- array(unlist(pieces), dim = c(nrow(df1),
                                           ncol(df1) - 1,
                                           length(pieces)))
        
        # compute sums across pieces
        rowSums(a, na.rm = TRUE, dims = 2)
        # [,1] [,2] [,3]
        # [1,]   12    6   32
        # [2,]    5    7   29
        # [3,]   43    2   22
        

        然后,您只需将 ID 列粘贴回去。

        【讨论】:

          猜你喜欢
          • 2016-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-05
          相关资源
          最近更新 更多