使用三个“拼图”填写数据集

时间:2012-04-03 23:07:50

标签: r

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

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

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

3 个答案:

答案 0 :(得分:2)

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
> 

答案 1 :(得分: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

答案 2 :(得分:1)

好的头衔!这与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列了。