如何用第二个DataFrame中的值填充二进制值的DataFrame?
问题
我有一个包含二进制0和1的DataFrame,需要用第二个DataFrame中的对应数值替换其中的1(0保持不变)。实际数据集有数千行,需要高效的实现方案。
示例数据
data <- data.frame(array(sample(c(0,1),25,replace=TRUE),dim=c(6,4))) colnames(data) <- c("sp1","sp2","sp3","sp4") size <- data.frame(array(c("sp1","sp2","sp3","sp4",13,16,14,12),dim=c(4,2)))
原始DataFrame输出
> data sp1 sp2 sp3 sp4 1 1 1 1 0 2 0 0 1 0 3 1 1 0 0 4 0 1 0 1 5 0 0 1 0 6 0 0 0 0
映射规则DataFrame输出
> size X1 X2 1 sp1 13 2 sp2 16 3 sp3 14 4 sp4 12
期望输出
sp1 sp2 sp3 sp4 1 13 16 14 0 2 0 0 14 0 3 13 16 0 0 4 0 16 0 12 5 0 0 14 0 6 0 0 0 0
高效解决方案
方法1:基础R向量化运算(推荐大数据量)
利用R的矩阵向量化运算,避免循环,效率极高:
# 先将size的映射值转为数值型 size$X2 <- as.numeric(size$X2) # 生成与data同维度的映射矩阵,按列匹配后相乘 result <- data * matrix(size$X2[match(colnames(data), size$X1)], nrow = nrow(data), ncol = ncol(data), byrow = TRUE)
原理:match(colnames(data), size$X1)匹配每列对应的映射值,生成和data结构一致的矩阵,与原DataFrame逐元素相乘——0乘任何数仍为0,1乘映射值得到目标数值。
方法2:tidyverse/dplyr实现
适合习惯tidyverse语法的用户,同样是向量化操作,效率优异:
library(dplyr) # 将size转换为命名向量(列名作为名字,映射值作为数值) size_vec <- size %>% tibble::deframe() %>% as.numeric() # 遍历所有列,用对应映射值替换1 result <- data %>% mutate(across(everything(), ~ .x * size_vec[cur_column()]))
内容的提问来源于stack exchange,提问作者Alex Howard
相关产品推荐
相关产品推荐

