使用R中的2个公共列,将df2中的错误值替换为df1中的真值
我有两个这样的数据帧使用R中的2个公共列,将df2中的错误值替换为df1中的真值,r,dataframe,dplyr,reshape,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(
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)
我不确定我是否朝着正确的方向前进。请帮助我输入如何有效地解决这个问题 既然您在这里进行文本子集设置,我将初始化为字符向量,而不是因子:
df1 <- data.frame(TEAM,EmpID,ManagerID,CODE, stringsAsFactors = FALSE)
df2 <- data.frame(TEAM,EmpID,ManagerID,CODE, stringsAsFactors = FALSE)
您希望创建一个列,其中的值要在此处合并,只需使用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
作为查找。这在merge函数中起作用(我没有意识到),但在我看来,这是一种糟糕的做法(NA
在R中指的是丢失的数据,而在这里它编码了一些东西)。我会考虑改变在数据中的表示方式。Edited:-)谢谢你,我对你想要的输出有点困惑。df1
中的code
列应设置为只更改df2
中的一行(在code
中带有
的一行)。如果其他行没有匹配的code
,它们将如何更改?我已经在那里提到,df1中的代码中的字母应该与df2中的代码中的第一个字母匹配。仅供参考,我的方法不起作用,可能是因为您的代码是一个因素,而不是字符。。。“不确定。”弗兰克,我把它转换成了字符,但还是不起作用。我正在检查可能出了什么问题。
library(data.table)
# convert data frames to data.table
setDT(df1)
setDT(df2)
df2[ , C_SHORT := substr(CODE,1,1)]
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