通过使用 R 中的 2 个公共(public)列将 df2 中的错误值替换为 df1 中的真实值

标签 r dataframe dplyr reshape

我有两个这样的数据框

TEAM <- c("PE","PE","MPI","TDT","HPT")
EmpID <- c (444452,444456,16822,339862,14828)    
ManagerID <- c(11499,11599,11899,11339,11559)
CODE <- c("F",NA,"A","H","G")
df1 <- data.frame(TEAM,EmpID,ManagerID,CODE)

TEAM <- c("MPI","TDT","HPT","PE","TDT","PE","MPI","TDT","HPT","PE")
EmpID <- c(444452,444452,444452,339862,339862,16822,339862,16822,14828,14828)
ManagerID <- c(11499,11499,11499,11339,11339,11899,11339,11899,11559,11559)
CODE <- c("A234","H665","G654","F616","H626","F234","H695","G954","G616",NA)
df2 <- data.frame(TEAM,EmpID,ManagerID,CODE)

仅当 TEAM 和 CODE(将 df1 中 CODE 列中的字母与 CODE 列的第一个字母匹配时,我才尝试使用 df1 中 ManagerID 和 EmpID 的真实值更新 df2 中 ManagerID 和 EmpID 的错误值在 df2).如果团队匹配但代码不正确,则错误值会保留并且不应替换为 df1 中的值。

我想要的输出是

   TEAM  EmpID ManagerID CODE
1   MPI  16822     11899 A234
2   TDT 339862     11339 H665
3   HPT  14828     11559 G654
4    PE 444452     11499 F616
5   TDT 339862     11339 H626
6    PE 444452     11499 F234
7   MPI 339862     11339 H695
8   TDT  16822     11899 G954
9   HPT  14828     11559 G616
10   PE 444452     11599 <NA>

您可以看到第 7 行和第 8 行保持不变,因为代码不匹配。

我在 Gregor 的帮助下为我的 previous question 尝试这样做

df2$ManagerID = df1$ManagerID[match(substr(df2$CODE, 1, 1), df1$CODE)]
df2$EmpID = df1$EmpID [match(substr(df2$CODE, 1, 1), df1$CODE)]

我不确定我的方向是否正确。请帮助我提供有关如何有效解决此问题的意见。

最佳答案

由于您在此处进行文本子集化,因此我将初始化为字符向量,而不是因子:

df1 <- data.frame(TEAM,EmpID,ManagerID,CODE, stringsAsFactors = FALSE)
df2 <- data.frame(TEAM,EmpID,ManagerID,CODE, stringsAsFactors = FALSE)

然后我会使用数据表(不是必需的,但更干净):

library(data.table)

# convert data frames to data.table
setDT(df1)
setDT(df2)

你想在此处创建一个具有要合并值的列,只需取 df2 的 CODE 的第一个字符即可

df2[ , C_SHORT := substr(CODE,1,1)]

然后我们在 TEAM/CODE 组合上合并两个数据框。这会在不存在任何匹配项的地方创建 NA。然后,测试是否有任何列是 NA,如果是则插入初始值

merge(x = df2,y = df1, by.x = c("TEAM","C_SHORT"), by.y = c("TEAM","CODE"), all.x = TRUE)[
  ,
  .(
    TEAM,
    EmpID = ifelse(is.na(EmpID.y), EmpID.x, EmpID.y), 
    ManagerID = ifelse(is.na(ManagerID.y), ManagerID.x, ManagerID.y),
    CODE
  )
  ]
    TEAM  EmpID ManagerID CODE
 1:  HPT  14828     11559 G654
 2:  HPT  14828     11559 G616
 3:  MPI  16822     11899 A234
 4:  MPI 339862     11339 H695
 5:   PE 444456     11599   NA
 6:   PE 444452     11499 F616
 7:   PE 444452     11499 F234
 8:  TDT  16822     11899 G954
 9:  TDT 339862     11339 H665
10:  TDT 339862     11339 H626

请注意:您在这里使用 NA 作为查找。这适用于合并功能(我没有意识到),但 IMO 这是不好的做法(R 中的 NA 实际上是指丢失的数据,而在这里它编码了一些东西)。我会考虑更改它在您的数据中的表示方式。

关于通过使用 R 中的 2 个公共(public)列将 df2 中的错误值替换为 df1 中的真实值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39153111/

相关文章:

python - 如果值是字符串,Pandas DataFrame 会执行某些操作

r - 根据组属性创建虚拟变量

r - 将NbClust()与不相似矩阵一起使用时,如何解决出现的错误?

r - 自动为所有可能的线性模型创建公式

python - 在 Pandas 数据框中取消嵌套记录列

r - 在 group_by 之后通过 mutate 应用函数

r - 基于几个不同的(子)分组(列)计算一列中唯一字符元素的数量

r - 根据公共(public)列组合 R 中的两个数据框

r - ggplot2:在 R 中创建视觉直观的时间线

python - Pandas 数据帧中任意两连续行之间的列差异比率的平均值