这是我的第一篇文章。如果我违反任何程序,请告诉我,我会相应提高自己。我对R来说相对比较新,所以我不断阅读有关它的书籍并且无法解决这个问题。
我正在组合多个数据框。有很多员工数据。我想要制作一个包含每个人的所有数据的主数据框(每一行都是关于一个员工的所有信息)。对于我们的一个数据框架,它已经以这种方式设置。
我们的HR文件出现了更大的问题。每次有人力资源“活动”时我们都会有一个条目。所以你得到加薪,你移动部门,数据更正等。为了给出一个基本的想法它看起来像这样:
Employee ID Event
1 Pay Raise
1 Promotion
1 Transfer
2 Data Cor
3 Raise
3 New Sup
我想将它与一个看起来像这样的数据框结合起来
`Employee ID Hire Date Salary
1 1/2/06 50000
2 4/6/15 100000
3 7/23/97 120000`
我想在末尾添加列,使用Employee ID进行匹配。所以基本上这是预期的结果:
Employee ID Hire Date Salary Event 1 Event 2 Event 3
1 1/2/06 50000 Raise Promotion Transfer
2 4/6/15 100000 Data Cor NA NA
3 7/23/97 120000 Raise New Sup NA
答案 0 :(得分:2)
使用下面的注释中定义的输入,为Seq
中的员工的第一行定义DF1
,为第二行定义“事件2”,依此类推。然后使用tapply
使用DF1
将Seq
从长格式转换为宽格式。用NA替换任何空字符串,然后将其与DF1
合并。没有包使用。
Seq <- paste("Event", ave(1:nrow(DF1), DF1$"Employee ID", FUN = seq_along))
wide <- with(DF1, tapply(Event, list(`Employee ID`, Seq), c))
wide[wide == ""] <- NA
merge(DF2, wide, by.x = 1, by.y = 0, all.x = TRUE)
,并提供:
Employee ID Hire Date Salary Event 1 Event 2 Event 3
1 Emp1 1/2/06 50000 Pay Raise Promotion Transfer
2 Emp2 4/6/15 100000 Data Cor <NA> <NA>
3 Emp3 7/23/97 120000 Raise New Sup <NA>
注意:可重复形式的输入为:
Lines1 <- "
Employee ID,Event
Emp1,Pay Raise
Emp1,Promotion
Emp1,Transfer
Emp2,Data Cor
Emp3,Raise
Emp3,New Sup"
DF1 <- read.csv(text = Lines1, check.names = FALSE, as.is = TRUE)
Lines2 <- "
Employee ID,Hire Date,Salary
Emp1,1/2/06,50000
Emp2,4/6/15,100000
Emp3,7/23/97,120000"
DF2 <- read.csv(text = Lines2, as.is = TRUE, check.names = FALSE)
答案 1 :(得分:2)
library(data.table)
DF1 <- fread("Employee_ID,Event
1,Pay Raise
1,Promotion
1,Transfer
2,Data Cor
3,Raise
3,New Sup", header=T, sep=",")
DF2 <- fread("Employee_ID,Hire_Date,Salary
1,1/2/06,50000
2,4/6/15,100000
3,7/23/97,120000", header=T, sep=",")
library(dplyr)
library(tidyr)
result <- DF1 %>%
group_by(Employee_ID) %>%
summarise(dummy=paste0(Event,collapse=",")) %>%
separate(dummy, into=c("Event_1","Event_2","Event_3"), sep=",", extra="drop", fill="right") %>%
left_join(., DF2, by="Employee_ID")
Employee_ID Event_1 Event_2 Event_3 Hire_Date Salary
1 1 Pay Raise Promotion Transfer 1/2/06 50000
2 2 Data Cor <NA> <NA> 4/6/15 100000
3 3 Raise New Sup <NA> 7/23/97 120000
答案 2 :(得分:1)
预期结果需要两个操作:
这可以使用data.table
:
library(data.table) # CRAN version 1.10.4 used
dcast(setDT(events), Employee_ID ~ paste0("Event_", rowid(Employee_ID)))[
setDT(employees), on = "Employee_ID"]
Employee_ID Event_1 Event_2 Event_3 Hire_Date Salary 1: 1 Pay Raise Promotion Transfer 1/2/06 50000 2: 2 Data Cor NA NA 4/6/15 100000 3: 3 Raise New Sup NA 7/23/97 120000 4: 4 NA NA NA 1/8/17 40000
请注意,我故意添加了第四名员工来模拟员工尚未记录任何事件的情况。
由于OP已请求在末尾添加列,setcolorder()
用于更改到位的列顺序,这样可以避免复制整个数据对象:
dcast(setDT(events), Employee_ID ~ paste0("Event_", rowid(Employee_ID)))[
setDT(employees), on = "Employee_ID"][
, setcolorder(.SD, c(names(employees), setdiff(names(.SD), names(employees))))]
Employee_ID Hire_Date Salary Event_1 Event_2 Event_3 1: 1 1/2/06 50000 Pay Raise Promotion Transfer 2: 2 4/6/15 100000 Data Cor NA NA 3: 3 7/23/97 120000 Raise New Sup NA 4: 4 1/8/17 40000 NA NA NA
为了完整起见,这是一个效率较低的替代方案,其中在从长格式转换为宽格式之前完成:
setDT(events)[setDT(employees), on = "Employee_ID"][
, dcast(.SD, Employee_ID + ... ~ paste0("Event_", rowid(Employee_ID)),
value.var = "Event")]
Employee_ID Hire_Date Salary Event_1 Event_2 Event_3 1: 1 1/2/06 50000 Pay Raise Promotion Transfer 2: 2 4/6/15 100000 Data Cor NA NA 3: 3 7/23/97 120000 Raise New Sup NA 4: 4 1/8/17 40000 NA NA NA
虽然这在编码方面需要较少的工作量,因为列以预期的顺序返回而没有额外调用setcolorder()
,但如果employee
,则在内存消耗和速度方面可能效率较低。有很多列。 OP已经提到每一行全部关于单个员工的信息(强调我的)。
events <- readr::read_table(
"Employee_ID Event
1 Pay Raise
1 Promotion
1 Transfer
2 Data Cor
3 Raise
3 New Sup")
employees <- readr::read_table(
"Employee_ID Hire_Date Salary
1 1/2/06 50000
2 4/6/15 100000
3 7/23/97 120000
4 1/8/17 40000")