融合具有相同维度的 dfs
Fusing dfs with equal dimmensions
我想融合 3 个数据框(AA
、AB
和 BB
),它们包含完全相同的维度并且永远不会包含相同坐标中的数字(如果一个包含一个数字,其他的将包含一个 NA
。对于所有数据帧,特定坐标包含 NA
也可能是真的)。这是我的输入:
AA <- 'pr_id sample1 sample2 sample3
AX-1 NA 120 130
AX-2 NA NA NA
AX-3 NA NA NA'
AA <- read.table(text=AA, header=T)
AB <- 'pr_id sample1 sample2 sample3
AX-1 100 NA NA
AX-2 NA 180 NA
AX-3 NA 120 NA'
AB <- read.table(text=AB, header=T)
BB <- 'pr_id sample1 sample2 sample3
AX-1 NA NA NA
AX-2 150 NA NA
AX-3 160 NA NA'
BB <- read.table(text=BB, header=T)
我的预期输出:
Fus <- 'pr_id sample1 sample2 sample3
AX-1 100 120 130
AX-2 150 180 NA
AX-3 160 120 NA'
Fus <- read.table(text=Fus, header=T)
执行此融合的一些想法?
这是给你一个矩阵的可能解决方案
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
Reduce(function(x, y) ifelse(is.na(x), y, x), L)
如果你想要一个数据框:
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- Reduce(function(x, y) ifelse(is.na(x), y, x), L)
as.data.frame(X) # Fus <- as.data.frame(X)
你也可以循环执行:
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- L[[1]]
for (i in 2:length(L)) X <- ifelse(is.na(X), L[[i]], X)
X
或
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- L[[1]]
for (i in 2:length(L)) X[is.na(X)] <- L[[i]][is.na(X)]
X
您还可以定义一个新的运算符来执行加法。
"%++%" <- Vectorize(function(x, y) {
if(is.na(x) && is.na(y)){
return(NA)
} else {
return(sum(c(x, y), na.rm=T))
}
})
cbind(AA[, 1, drop=F], matrix(as.matrix(AA[, 2:4]) %++%
as.matrix(AB[, 2:4]) %++%
as.matrix(BB[, 2:4]), ncol=3))
# pr_id 1 2 3
# 1 AX-1 100 120 130
# 2 AX-2 150 180 NA
# 3 AX-3 160 120 NA
我想融合 3 个数据框(AA
、AB
和 BB
),它们包含完全相同的维度并且永远不会包含相同坐标中的数字(如果一个包含一个数字,其他的将包含一个 NA
。对于所有数据帧,特定坐标包含 NA
也可能是真的)。这是我的输入:
AA <- 'pr_id sample1 sample2 sample3
AX-1 NA 120 130
AX-2 NA NA NA
AX-3 NA NA NA'
AA <- read.table(text=AA, header=T)
AB <- 'pr_id sample1 sample2 sample3
AX-1 100 NA NA
AX-2 NA 180 NA
AX-3 NA 120 NA'
AB <- read.table(text=AB, header=T)
BB <- 'pr_id sample1 sample2 sample3
AX-1 NA NA NA
AX-2 150 NA NA
AX-3 160 NA NA'
BB <- read.table(text=BB, header=T)
我的预期输出:
Fus <- 'pr_id sample1 sample2 sample3
AX-1 100 120 130
AX-2 150 180 NA
AX-3 160 120 NA'
Fus <- read.table(text=Fus, header=T)
执行此融合的一些想法?
这是给你一个矩阵的可能解决方案
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
Reduce(function(x, y) ifelse(is.na(x), y, x), L)
如果你想要一个数据框:
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- Reduce(function(x, y) ifelse(is.na(x), y, x), L)
as.data.frame(X) # Fus <- as.data.frame(X)
你也可以循环执行:
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- L[[1]]
for (i in 2:length(L)) X <- ifelse(is.na(X), L[[i]], X)
X
或
L <- lapply(list(AA, AB, BB), function(x) { row.names(x) <- x[[1]]; as.matrix(x[-1])})
X <- L[[1]]
for (i in 2:length(L)) X[is.na(X)] <- L[[i]][is.na(X)]
X
您还可以定义一个新的运算符来执行加法。
"%++%" <- Vectorize(function(x, y) {
if(is.na(x) && is.na(y)){
return(NA)
} else {
return(sum(c(x, y), na.rm=T))
}
})
cbind(AA[, 1, drop=F], matrix(as.matrix(AA[, 2:4]) %++%
as.matrix(AB[, 2:4]) %++%
as.matrix(BB[, 2:4]), ncol=3))
# pr_id 1 2 3
# 1 AX-1 100 120 130
# 2 AX-2 150 180 NA
# 3 AX-3 160 120 NA