如何匹配和分裂

时间:2015-07-23 17:04:37

标签: r data.table

给出以下数据表:

df1 <- data.table(V1=c("A","C","D","B"),V2=c(0,2,0,2),V3=c(2,0,2,0))
df2 <- data.table(V1=c("A","B","C","D"),V2=c(4,2,4,2))
df1
df2
> df1
   V1 V2 V3
1:  A  0  2
2:  C  2  0
3:  D  0  2
4:  B  2  0
> df2
   V1 V2
1:  A  4
2:  B  2
3:  C  4
4:  D  2

我寻求以下内容:对于df1的每个数值,使用V1作为键,将该值除以df2中的相应值。结果数据表应为:

> df3
   V1 V2   V3
1:  A  0    0.5
2:  C  0.5  0
3:  D  0    1
4:  B  1    0

你能帮帮我吗?

非常感谢提前。

2 个答案:

答案 0 :(得分:3)

使用data.table

setkey(df1, V1)
df1[df2,.(V1,V2=V2/i.V2, V3=V3/i.V2)]
#   V1  V2  V3
#1:  A 0.0 0.5
#2:  B 1.0 0.0
#3:  C 0.5 0.0
#4:  D 0.0 1.0

有关更多选项,请参阅评论。

答案 1 :(得分:2)

这适用于您的示例,尽管它对于更多列不太可扩展。您的真实世界用法是否使用两个具有相同列名的表?

df3<-merge(df1,df2,"V1")[,list(V2=V2.x/V2.y, V3=V3/V2.y),by=V1]

这是一种可以处理更多列的方法,即使它们在每个表中可能有也可能没有相同的名称。这依赖于匹配的列被命名为V1,但是它不依赖于列名。即使在df2中有超过2列,它也会取V1之后的第一列作为除数。

#The first six lines just change column names incase they're the same
oldnames1<-names(df1)[!names(df1) %in% "V1"]
oldnames2<-names(df2)[!names(df2) %in% "V1"]
newnames1<-paste0("x",oldnames1)
newnames2<-paste0("y",oldnames2)
setnames(df1,oldnames1,newnames1)
setnames(df2,oldnames2,newnames2)
df3<-merge(df1,df2,by="V1")
df3[,(oldnames1):=.SD[,!newnames2,with=FALSE]/get(newnames2),by="V1"]
df3[,c(newnames1,newnames2):=NULL]
setnames(df1,newnames1,oldnames1)
setnames(df2,newnames2,oldnames2)