给出以下数据表:
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
你能帮帮我吗?
非常感谢提前。
答案 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)