匹配名称并将数据集更改为r中的宽格式

时间:2015-04-08 01:14:23

标签: r matching

我有两个这样的df:

Name1            Task   Bond    Goal    Name2          Rapport  Client
Abigail Adkins   24     20       25     Adam Tharkur    4.08    4.29
Abigail Brusse   25     26       24     Adam Tharkur    6.08    6
Adam Tharker     24     24       24     Anne Corinne    5.5     6.29
Adriel Parks     27     18       26     Alan Hamaoui    7       6.43
Allison Mofsky   21     28       20     Alyssa Sorrells 5.67    5.29

df1有Name1,Task,Bond和Goal,df2有Name2,Rapport和Client。 我的目标是选择两个dfs中相同的名称,并将其五个分数设为:

Name   Task     Bond     Goal    Rapport1   Client1  Rapport2   Client2
Adam    24      24       24      4.08       4.29     6.08       6

每个名字可能有多个观察(少于10个),比如" Adam",我只想匹配选择中的第一个名字,因为有些我没有输入姓氏。有人有什么想法吗?非常感谢你。

可重复数据:

dat <- read.csv(text="Name1,Task,Bond,Goal,Name2,Rapport,Client
Abigail Adkins,24,20,25,Adam Tharkur,4.08,4.29
Abigail Brusse,25,26,24,Adam Tharkur,6.08,6
Adam Tharker,24,24,24,Anne Corinne,5.5,6.29
Adriel Parks,27,18,26,Alan Hamaoui,7,6.43
Allison Mofsky,21,28,20,Alyssa Sorrells,5.67,5.29",header=TRUE,stringsAsFactors=FALSE)

df1 <- dat[1:4]
df2 <- dat[5:7]

1 个答案:

答案 0 :(得分:4)

&#39;名字&#39;可以使用submerge两个数据集通过&#39;名称&#39;提取。列,为分组变量创建序列索引(&#39; indx&#39;),并使用reshape更改&#39; long&#39; ;广泛的&#39;。

df1$Name1 <- sub(' .*$', '', df1$Name1)
df2$Name2 <- sub(' .*$', '', df2$Name2)
dfN <- merge(df1, df2, by.x='Name1', by.y='Name2')
dfN$indx <- with(dfN, ave(seq_along(Name1), Name1, FUN=seq_along))
reshape(dfN, idvar=c('Name1', 'Task', 'Bond', 'Goal'), 
             timevar='indx', direction='wide')
#   Name1 Task Bond Goal Rapport.1 Client.1 Rapport.2 Client.2
#1  Adam   24   24   24      4.08     4.29      6.08        6

或者我们可以使用data.table的开发版本,即v1.9.5。安装说明是here

删除&#39;姓氏&#39;在&#39;名称&#39;两个数据集的列(如上所示),然后转换&#39; df1&#39;到&#39; data.table&#39; (setDT(df1)),并将键列设置为&#39; Name1&#39; (setkey(.., Name1))。加入&#39; df2&#39;,为&#39; Name1&#39;创建一个序列列(&#39; N&#39;),然后使用dcast。在devel版本中,dcast可以包含多个value.var列。

library(data.table)#v1.9.5+
dcast(setkey(setDT(df1), Name1)[df2, nomatch=0][, N:=1:.N, Name1],
             ...~N, value.var= c('Rapport', 'Client'))
#    Name1 Task Bond Goal 1_Rapport 2_Rapport 1_Client 2_Client
#1:  Adam   24   24   24      4.08      6.08     4.29        6