使用R

时间:2016-08-25 19:15:23

标签: r dataframe dplyr reshape

我有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)]

我不确定自己是否朝着正确的方向前进。请帮助我了解如何有效地解决这个问题。

1 个答案:

答案 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实际上是指丢失的数据,而在这里它编码的东西)。我会考虑更改数据中的表示方式。