我有2个像这样的数据框
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)
我正在尝试更新ManagerID&amp;的错误值在df2中的EmpID具有ManagerID和&amp;的真实值。仅当TEAM&amp; CODE(将df1中CODE列中的字母与df2中CODE列的第一个字母相匹配)。如果团队匹配但代码不正确,则保留错误的值,不应使用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行和第7行。由于代码不匹配,因此保持不变。
我尝试在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)]
我不确定自己是否朝着正确的方向前进。请帮助我了解如何有效地解决这个问题。
答案 0 :(得分:1)
由于你在这里做文本子集,我会初始化为字符向量,而不是因素:
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
s,其中不存在任何匹配项。然后,测试任何列是否为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
实际上是指丢失的数据,而在这里它编码的东西)。我会考虑更改数据中的表示方式。