【问题标题】:Merging rows in R based on several parameters基于几个参数合并R中的行
【发布时间】:2018-05-16 19:51:42
【问题描述】:

我有一个数据框df,其中包含近 100,000 个显示我的程序联系人列表的数据。该列表有一列显示与联系人关联的程序program 和组织OrgName。它还有一组三列,显示联系人是否与列名称中标识的角色相关联:Role_PrimaryRole_CommsRole_Signatory。每当联系人在多个程序中或在程序中具有多个角色时,都会为该联系人创建另一行,并且联系人角色字段值会发生变化。请参阅下面的示例。

First   Last    C_ID    OrgName O_ID Program    Role_Primary    Role_Comms  Role_Signatory
John    Smith   10045   Acme    901  Buildings  X       
John    Smith   10045   Acme    901  Buildings                  X   
John    Smith   10045   Acme    901  Homes      X       
Teddy   Bush    10046   Acme    901  Buildings  X       
Teddy   Bush    10046   Acme    901  Buildings                              X
Jess    Clinton 10050   Consult 904  Homes                                  X
Jess    Clinton 10050   Consult 904  Homes      X       
Jess    Clinton 10050   Consult 904  Homes      X   

出于演示目的,我试图尽量减少行数。具体来说,如果一个联系人在同一个组织和同一个程序中,我只希望该联系人出现在一行上(而不是目前的几行),并在相关列中注明联系人角色。见下文。

First   Last    C_ID    OrgName O_ID Program    Role_Primary    Role_Comms  Role_Signatory
John    Smith   10045   Acme    901  Buildings  X               X   
John    Smith   10045   Acme    901  Homes      X       
Teddy   Bush    10046   Acme    901  Buildings  X               X
Jess    Clinton 10050   Consult 904  Homes      X               X           X

重新创建上面的两个表:

 table1<-structure(list(First = structure(c(2L, 2L, 2L, 3L, 3L, 1L, 1L, 
1L), .Label = c("Jess", "John", "Teddy"), class = "factor"), 
    Last = structure(c(3L, 3L, 3L, 1L, 1L, 2L, 2L, 2L), .Label = c("Bush", 
    "Clinton", "Smith"), class = "factor"), C_ID = c(10045L, 
    10045L, 10045L, 10046L, 10046L, 10050L, 10050L, 10050L), 
    OrgName = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("Acme", 
    "Consult"), class = "factor"), O_ID = c(901L, 901L, 901L, 
    901L, 901L, 904L, 904L, 904L), Program = structure(c(1L, 
    1L, 2L, 1L, 1L, 2L, 2L, 2L), .Label = c("Buildings", "Homes"
    ), class = "factor"), Role_Primary = structure(c(2L, 1L, 
    2L, 2L, 1L, 1L, 2L, 1L), .Label = c("", "X"), class = "factor"), 
    Role_Comms = structure(c(1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L), .Label = c("", 
    "X"), class = "factor"), Role_Signatory = structure(c(1L, 
    1L, 1L, 1L, 2L, 2L, 1L, 1L), .Label = c("", "X"), class = "factor")), .Names = c("First", 
"Last", "C_ID", "OrgName", "O_ID", "Program", "Role_Primary", 
"Role_Comms", "Role_Signatory"), class = "data.frame", row.names = c(NA, 
-8L))

table2<-structure(list(First = structure(c(2L, 2L, 3L, 1L), .Label = c("Jess", 
"John", "Teddy"), class = "factor"), Last = structure(c(3L, 3L, 
1L, 2L), .Label = c("Bush", "Clinton", "Smith"), class = "factor"), 
    C_ID = c(10045L, 10045L, 10046L, 10050L), OrgName = structure(c(1L, 
    1L, 1L, 2L), .Label = c("Acme", "Consult"), class = "factor"), 
    O_ID = c(901L, 901L, 901L, 904L), Program = structure(c(1L, 
    2L, 1L, 2L), .Label = c("Buildings", "Homes"), class = "factor"), 
    Role_Primary = structure(c(1L, 1L, 1L, 1L), .Label = "X", class = "factor"), 
    Role_Comms = structure(c(2L, 1L, 1L, 2L), .Label = c("", 
    "X"), class = "factor"), Role_Signatory = structure(c(1L, 
    1L, 2L, 2L), .Label = c("", "X"), class = "factor")), .Names = c("First", 
"Last", "C_ID", "OrgName", "O_ID", "Program", "Role_Primary", 
"Role_Comms", "Role_Signatory"), class = "data.frame", row.names = c(NA, 
-4L))

【问题讨论】:

  • 你知道如何使用dplyr吗?如果是这样,只需将所有 role 变量转换为整数标志(而不是“x”),然后按非 role 变量分组并使用 summarise() 创建新的 role 变量,就很容易了.如果你dput()你的数据样本,我可以为你做。
  • 克里斯 我不熟悉如何使用 dplyr 来做到这一点。我在原始问题中添加了 dput 数据。谢谢。
  • 看起来有人已经回答了。我认为这将回答对你有用。如果没有,请告诉我

标签: r merge apply


【解决方案1】:

输入

df <- data.table::fread("First      Last        C_ID        OrgName     O_ID    Program Role_Primary    Role_Comms  Role_Signatory
John        Smith       10045   Acme        901 Buildings   X       
John        Smith       10045   Acme        901 Buildings       X   
John        Smith       10045   Acme        901 Homes       X       
Teddy       Bush        10046   Acme        901 Buildings   X       
Teddy       Bush        10046   Acme        901 Buildings           X
Jess        Clinton     10050   Consult     904 Homes               X
Jess        Clinton     10050   Consult     904 Homes       X       
Jess        Clinton     10050   Consult     904 Homes       X       ")

合并行的代码:

library(dplyr)
library(tidyr)

df %>% 
  gather(Role, Member, Role_Primary:Role_Signatory) %>% 
  filter(!is.na(Member) & nchar(trimws(Member))>0) %>% 
  distinct() %>% 
  mutate(Role = factor(Role, unique(Role))) %>% 
  spread(Role, Member)

输出

First    Last  C_ID OrgName O_ID   Program Role_Primary Role_Comms Role_Signatory
1  Jess Clinton 10050 Consult  904     Homes            X       <NA>              X
2  John   Smith 10045    Acme  901 Buildings            X          X           <NA>
3  John   Smith 10045    Acme  901     Homes            X       <NA>           <NA>
4 Teddy    Bush 10046    Acme  901 Buildings            X       <NA>              X

请注意 distinct() 行存在,因为在输入示例中,Jess Clinton 的相同角色列出了两次。

【讨论】:

  • 我尝试了解决方案,首先导入您在 df 中提供的示例数据。但是,这并没有读入 R。然后我尝试使用我在对原始问题的编辑中提供的 dput 数据来实现解决方案。但是,我收到以下消息:过滤器错误(., !is.na(Member) & nchar(trimws(Member)) > 0) : object 'Member' not found 另外:警告消息:1:在数据中。 matrix(data) :强制引入的 NA 2:在 data.matrix(data) 中:强制引入的 NA >
  • 要使用此处的代码,您必须安装用于此解决方案的软件包。要使用 fread 输入数据,您必须安装 data.table 包。对于合并行的代码,您必须安装 dplyr 和 tidyr。尝试运行代码时是否安装了这 3 个包?
【解决方案2】:

我的方法是创建一个唯一标识符列,使用该列过滤保存为df2 的唯一行,然后使用df 中的完整数据填充df2 中的缺失值。

library(dplyr)
#make a uniqueID  column by pasting any of the relevant unique values together
df$uniqueID<-paste0(df$C_ID,df$OrgName, df$Program)
#remove duplicate rows, store as df2 
df2<-df[!duplicated(df$uniqueID),] 

使用uniqueID 的索引在df2 中查找相同uniqueIDany() X。

for(id in 1:nrow(df2)){
Xfind<-df$Role_Primary[df$uniqueID %in% df2$uniqueID[id]]
if (any(Xfind=="X")){df2$Role_Primary[id]<-"X"}
Xfind2<-df$Role_Signatory[df$uniqueID %in% df2$uniqueID[id]] 
if (any(Xfind2=="X")){df2$Role_Signatory[id]<-"X"}
Xfind3<-df$Role_Comms[df$uniqueID %in% df2$uniqueID[id]]
if (any(Xfind3=="X")){df2$Role_Comms[id]<-"X"}
}

这将为您提供所需的输出:

df2

【讨论】:

    猜你喜欢
    • 2011-12-06
    • 2020-07-17
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    相关资源
    最近更新 更多