通过获取一列并将其添加到行来连接数据帧

时间:2017-08-05 23:12:43

标签: r dataframe

这是我的第一篇文章。如果我违反任何程序,请告诉我,我会相应提高自己。我对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

3 个答案:

答案 0 :(得分:2)

使用下面的注释中定义的输入,为Seq中的员工的第一行定义DF1,为第二行定义“事件2”,依此类推。然后使用tapply使用DF1Seq从长格式转换为宽格式。用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=",")

dplyr&amp; tidyr解决方案

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)

预期结果需要两个操作:

  • 将事件文件从长格式转换为宽格式
  • 加入HR文件中的其他员工基础数据

这可以使用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")