You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何比对两个DataFrame的CNPJ与ANO列并给benford列赋值?

解决R中双列匹配并赋值的问题

我来帮你搞定这个双列匹配赋值的需求——你之前用单列匹配的思路没问题,只需要把逻辑扩展到同时匹配CNPJ和ANO两列就行。下面给你两种常用的实现方法,分别基于Base R和tidyverse工具包,都能得到你想要的结果:

先确认数据结构

首先先把你提供的两个DataFrame代码放出来,方便复现和验证:

# caracteristica_receita 数据结构
caracteristica_receita <- structure(list(CNPJ = c(1234, 5678, 91012, 12346, 96385, 87952, 7789, 2535, 4459, 5457), 
                                         NOME_INSTITUICAO = c("XXXX", "AAAA", "BBBB", "CCCC", "DDDDD", "RRRR", "FFFFF", "GGGGG", "HHHHHH", "IIIIIII"), 
                                         ano_fundacao = c(1993, 1993, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994), 
                                         ANO = c(2014, 2015, 2014, 2015, 2016, 2014, 2014, 2015, 2016, 2017), 
                                         benford = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), 
                                    .Names = c("CNPJ", "NOME_INSTITUICAO", "ano_fundacao", "ANO", "benford"), 
                                    row.names = c(NA, 10L), class = "data.frame")

# coop_receita_anos2d 数据结构
coop_receita_anos2d <- structure(list(CNPJ = c(1234, 5678, 916862, 12346, 96385, 87952, 7789, 2535, 4459, 46868), 
                                      ANO = c(2014, 2014, 0, 0, 0, 2014, 0, 0, 0, 0)), 
                                 .Names = c("CNPJ", "ANO"), 
                                 row.names = c(1L, 3L, 7L, 11L, 15L, 19L, 23L, 27L, 31L, 35L), class = "data.frame")

方法一:Base R 实现

核心思路是把每行的CNPJ和ANO拼接成唯一标识,通过判断这个标识是否存在于另一个数据框的拼接标识中,来确定匹配行:

# 生成两列拼接的匹配键(用下划线分隔避免数值拼接歧义)
caracteristica_keys <- with(caracteristica_receita, paste(CNPJ, ANO, sep = "_"))
coop_keys <- with(coop_receita_anos2d, paste(CNPJ, ANO, sep = "_"))

# 找到匹配的行索引并给benford列赋值1
match_indices <- caracteristica_keys %in% coop_keys
caracteristica_receita$benford[match_indices] <- 1

这种方法简单直接,不需要额外安装包,适合习惯Base R的用户。

方法二:tidyverse (dplyr) 实现

如果你平时用dplyr处理数据,用left_join的方式会更直观,逻辑也更清晰:

library(dplyr)

caracteristica_receita <- caracteristica_receita %>%
  # 左连接匹配CNPJ和ANO,给匹配到的行添加标记flag
  left_join(coop_receita_anos2d %>% mutate(match_flag = 1), 
            by = c("CNPJ", "ANO")) %>%
  # 根据标记更新benford列:匹配到的设为1,没匹配到的保留原0
  mutate(benford = ifelse(!is.na(match_flag), 1, benford)) %>%
  # 移除临时的标记列
  select(-match_flag)

这种方法可读性更强,尤其是处理复杂数据匹配场景时,逻辑不容易出错。

验证结果

运行上面任意一种方法后,你得到的caracteristica_receita就会和你期望的输出完全一致:

# 最终输出结果
structure(list(CNPJ = c(1234, 5678, 91012, 12346, 96385, 87952, 7789, 2535, 4459, 5457), 
               NOME_INSTITUICAO = c("XXXX", "AAAA", "BBBB", "CCCC", "DDDDD", "RRRR", "FFFFF", "GGGGG", "HHHHHH", "IIIIIII"), 
               ano_fundacao = c(1993, 1993, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994), 
               ANO = c(2014, 2015, 2014, 2015, 2016, 2014, 2014, 2015, 2016, 2017), 
               benford = c(1, 0, 0, 0, 0, 1, 0, 0, 0, 0)), 
          .Names = c("CNPJ", "NOME_INSTITUICAO", "ano_fundacao", "ANO", "benford"), 
          row.names = c(NA, 10L), class = "data.frame")

内容的提问来源于stack exchange,提问作者RxT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:45:45