如何计算R中2个数据帧之间具有相同值的行数

如何计算R中2个数据帧之间具有相同值的行数,r,data.table,R,Data.table,我有两个数据帧 df1 <- data.frame(col11=c("a","a","a","b","b"), col=c(1,2,3,4,5)) df2 <- data.frame(col21=c("c","c","d","d","d"), col=c(1,5,1,2,5)) df3

我有两个数据帧

df1 <- data.frame(col11=c("a","a","a","b","b"), col=c(1,2,3,4,5))
df2 <- data.frame(col21=c("c","c","d","d","d"), col=c(1,5,1,2,5))
df3 <- data.frame(group11=c("a","a","b","b"), group21=c("c","d","c","d"), index1=c(1,2,1,1))
df4 <- data.frame(group11=c("a","a","b","b"), group21=c("c","d","c","d"), index2=c(5,6,4,5))

  
要生成此数据帧

df5 <- data.frame(group11=("a","a","b","b"), group21=c("c","d","c","d"), index3=c(0.2,0.33,0.25,0.2))
您能帮助我在不使用联接表和不创建中间数据帧的情况下获得结果数据帧吗?谢谢。

您可以定义两个矢量化函数来完成这项工作

首先,我们根据两个数据帧的列**将它们拆分成一个列表

L <- c(split(df1$col, df1$col11), split(df2$col, df2$col21))
使用来自矩阵外积的outer。我们只需要[1:2,3:4]作为结果的子集

res3 <- as.vector(outer(L, L, FUN3)[1:2, 3:4])
res4 <- as.vector(outer(L, L, FUN4)[1:2, 3:4])
最后我们把所有的东西都绑定在一起并设置名称

编辑 outer给出整个矩阵的外积。因为我们只是比较a,b和c,d,我们只需要得到矩阵的一部分。在本例中,我们只需要第一个象限,即右上角4x4子矩阵,即行1:2和列3:4

您可以定义两个矢量化函数来完成这项工作

首先,我们根据两个数据帧的列**将它们拆分成一个列表

L <- c(split(df1$col, df1$col11), split(df2$col, df2$col21))
使用来自矩阵外积的outer。我们只需要[1:2,3:4]作为结果的子集

res3 <- as.vector(outer(L, L, FUN3)[1:2, 3:4])
res4 <- as.vector(outer(L, L, FUN4)[1:2, 3:4])
最后我们把所有的东西都绑定在一起并设置名称

编辑 outer给出整个矩阵的外积。因为我们只是比较a,b和c,d,我们只需要得到矩阵的一部分。在本例中,我们只需要第一个象限,即右上角4x4子矩阵,即行1:2和列3:4

不幸的是,这是一种仍然有很多人加入的方法

图书馆数据表 df1 >1:a c 150.2000000 >2:AD260.3333 >3:b c 14 0.2500000 >4:b d 150.2000000 我们使用data.table的引用语义在调用中直接更新data.table,这样我们就没有额外的对象了

CJ。。。就是设置所有独特的组合。 index1:=df1[df2,…]是连接语法,后跟确定每个组合的count.N。注意,我认为不将此连接回res是安全的,因为keyby将产生与CJ中相同的顺序。 地图。。。调用是一个奇特的循环,我们为res中的每一行对每一个组合进行过滤。我将根据对col是否唯一的反馈进行更改。 最后,值得指出的是,没有简单的解决方案。将有一些中间计算步骤来防止这些调用过长。

不幸的是,这里有一种方法仍然有很多连接

图书馆数据表 df1 >1:a c 150.2000000 >2:AD260.3333 >3:b c 14 0.2500000 >4:b d 150.2000000 我们使用data.table的引用语义在调用中直接更新data.table,这样我们就没有额外的对象了

CJ。。。就是设置所有独特的组合。 index1:=df1[df2,…]是连接语法,后跟确定每个组合的count.N。注意,我认为不将此连接回res是安全的,因为keyby将产生与CJ中相同的顺序。 地图。。。调用是一个奇特的循环,我们为res中的每一行对每一个组合进行过滤。我将根据对col是否唯一的反馈进行更改。
最后,值得指出的是,没有简单的解决方案。将有中间计算步骤来防止这些调用过长。

您能否添加有关如何计算index2的详细信息?col中只有5个总数,这意味着在index2中不可能得到6的结果。但是,如果只是长度,我会按照你的计算。你能补充一下index2是如何计算的吗?col中只有5个总数,这意味着在index2中不可能得到6的结果。但是,如果它只是长度,我会按照您的计算。对于代码res[,index1:=df1[df2,on=.col][,.N,keyby=.col11,col21]$N],它会一直显示evaljsub,SDenv,parent.frame中的errorError:object'col'not found。我不知道为什么我不能重现这个错误。你能运行df1[df2,on=.col]的连接,看看是否有错误吗?还有,你有什么版本的data.table?我使用的是1.12.8版本。如果你对这种方法感兴趣,请告诉我df[df2,on=.col]-我重新安装了data.table,仍然没有问题。对于代码res[,index1:=df1[df2,on=.col][,.N,keyby=.col11,col21]$N],它在evaljsub,SDenv,parent.frame:object'col'中不断显示错误。我不知道为什么我无法重现错误。你能运行df1[df2,on=.col]的联接吗看看是否有错误?还有,你有什么版本的data.table?我使用的是1.12.8版本。如果你对这种方法感兴趣,请告诉我df[df2,on=.co
l] -我重新安装了data.table,但仍然没有问题。请解释一下为什么我们只需要[1:2,3:4]作为结果的子集?我的实际df有多行,但res3和res4只有4行。@Liselotte是的,请参见编辑,这有意义吗?@Liselotte注意,我在编辑中添加了一个节名。很抱歉,lg1和LG2是什么?请解释为什么我们只需要[1:2,3:4]作为结果的子集?我的实际df有多行,但res3和res4只有4行。@Liselotte是的,请参见编辑,这有意义吗?@Liselotte注意,我在编辑中添加了一个节名。很抱歉,lg1和lg2是什么
setNames(cbind.data.frame(nm, res3 / res4), c("group11", "group21", "index3"))
#   group11 group21    index3
# 1       a       c 0.2000000
# 2       b       c 0.2500000
# 3       a       d 0.3333333
# 4       b       d 0.2000000
(res3 <- outer(L, L, FUN3))
#   a b c d
# a 3 0 1 2
# b 0 2 1 1
# c 1 1 2 2
# d 2 1 2 3
(rows <- which(rownames(res3) %in% unique(df1$col11)))  ## i.e. %in% c("a", "b")
# [1] 1 2
(cols <- which(colnames(res3) %in% unique(df2$col21)))  ## i.e. %in% c("c", "d")
# [1] 3 4

(res3 <- as.vector(res3[rows, cols]))
# [1] 1 1 2 1
lg1 <- seq(length(unique(df1$col11)))
lg2 <- seq(length(unique(df2$col21))) + length(unique(df1$col11))

nm <- do.call(rbind, strsplit(as.vector(outer(lg1, lg2, paste)), " "))
(nm <- apply(nm, 1:2, function(x) names(L)[as.double(x)]))
#     [,1] [,2]
# [1,] "a"  "c" 
# [2,] "b"  "c" 
# [3,] "a"  "d" 
# [4,] "b"  "d"