R 从两个数据帧创建评分矩阵

R 从两个数据帧创建评分矩阵,r,dataframe,data.table,R,Dataframe,Data.table,我试图比较存储在两个数据帧(foo,bar)中的变量集(X)。每个X都是唯一的自变量,最多有10个Y值与其关联。我想通过比较每个foo.X和每个bar.X的共同值Y的数量来比较它们,因此输出可以是一个矩阵,其轴的长度为foo.X和bar.X 这个简单的foo和bar示例希望返回一个2x2矩阵,比较a,b和c,d: foo <- data.frame(x= c('a', 'a', 'a', 'b', 'b', 'b'), y=c('ab', 'ac', 'ad', 'ae', 'fx', '

我试图比较存储在两个数据帧(
foo
bar
)中的变量集(
X
)。每个
X
都是唯一的自变量,最多有10个
Y
值与其关联。我想通过比较每个foo.X和每个bar.X的共同值
Y
的数量来比较它们,因此输出可以是一个矩阵,其轴的长度为foo.X和bar.X

这个简单的foo和bar示例希望返回一个2x2矩阵,比较a,b和c,d:

foo <- data.frame(x= c('a', 'a', 'a', 'b', 'b', 'b'), y=c('ab', 'ac', 'ad', 'ae', 'fx', 'fy'))
bar <- data.frame(x= c('c', 'c', 'c', 'd', 'd', 'd'), y=c('ab', 'xy', 'xz', 'xy', 'fx', 'xz'))
编写一个函数,用于比较两个堆叠列表中的成员资格

comparelists <- function(list1, list2) {
  for (i in list1){ 
    for (j in list2){
      count <- 0
      if (i[[1]] %in% j[[1]]) count <- count + 1
    }
  }
  return count
  }

comparelists要做到这一点,必须有上百种方法;我觉得这是一个相对简单的例子:

library(reshape2)
foo <- data.frame(x = c('a', 'a', 'a', 'b', 'b', 'b'), 
                  y = c('ab', 'ac', 'ad', 'ae', 'fx', 'fy'))
bar <- data.frame(x = c('c', 'c', 'c', 'd', 'd', 'd'), 
                  y = c('ab', 'xy', 'xz', 'xy', 'fx', 'xz'))

# Create a function that counts the number of common elements in two groups
nShared <- function(A, B) {
    length(intersect(with(foo, y[x==A]), with(bar, y[x==B])))
}

# Enumerate all combinations of groups in foo and bar
(combos <- expand.grid(foo.x=unique(foo$x), bar.x=unique(bar$x)))
#   foo.x bar.x
# 1     a     c
# 2     b     c
# 3     a     d
# 4     b     d

# Find number of elements in common among all pairs of groups
combos$n <- mapply(nShared, A=combos$foo.x, B=combos$bar.x)

# Reshape results into matrix form
dcast(combos, foo.x ~ bar.x)
#   foo.x c d
# 1     a 1 0
# 2     b 0 1
library(重塑2)

要做到这一点,必须有一百种方法;我觉得这是一个相对简单的例子:

library(reshape2)
foo <- data.frame(x = c('a', 'a', 'a', 'b', 'b', 'b'), 
                  y = c('ab', 'ac', 'ad', 'ae', 'fx', 'fy'))
bar <- data.frame(x = c('c', 'c', 'c', 'd', 'd', 'd'), 
                  y = c('ab', 'xy', 'xz', 'xy', 'fx', 'xz'))

# Create a function that counts the number of common elements in two groups
nShared <- function(A, B) {
    length(intersect(with(foo, y[x==A]), with(bar, y[x==B])))
}

# Enumerate all combinations of groups in foo and bar
(combos <- expand.grid(foo.x=unique(foo$x), bar.x=unique(bar$x)))
#   foo.x bar.x
# 1     a     c
# 2     b     c
# 3     a     d
# 4     b     d

# Find number of elements in common among all pairs of groups
combos$n <- mapply(nShared, A=combos$foo.x, B=combos$bar.x)

# Reshape results into matrix form
dcast(combos, foo.x ~ bar.x)
#   foo.x c d
# 1     a 1 0
# 2     b 0 1
library(重塑2)

foo这里有一个使用
merge

library(reshape2)
df1 <- merge(foo, bar, by = 'y')
dcast(df1, x.x ~ x.y, length)

  x.x c d
1   a 1 0
2   b 0 1

下面是一个使用
merge

library(reshape2)
df1 <- merge(foo, bar, by = 'y')
dcast(df1, x.x ~ x.y, length)

  x.x c d
1   a 1 0
2   b 0 1


美好的我看到你扩展到一个大网格,计算重叠,然后重铸。优雅的但如果foo和bar实际上有数千名成员呢?你会改变你的方法吗?除非计算真的慢下来,否则我不会改变它。但我认为这应该可以很好地扩展到更大的数据集。谢谢Josh。我是R方面的新手,没有使用过intersect、expand.grid、dcast或mapply,所以除了快速回答之外,这真是一个帮助!在组合之后,data.frames的列可能属于类
字符
,而不是
因子
,因此
levels()
对它们不起作用。我已经编辑了答案,将
levels()
替换为
unique()
。它现在应该可以同时处理字符和因子列。很好!我看到你扩展到一个大网格,计算重叠,然后重铸。优雅的但如果foo和bar实际上有数千名成员呢?你会改变你的方法吗?除非计算真的慢下来,否则我不会改变它。但我认为这应该可以很好地扩展到更大的数据集。谢谢Josh。我是R方面的新手,没有使用过intersect、expand.grid、dcast或mapply,所以除了快速回答之外,这真是一个帮助!在组合之后,data.frames的列可能属于类
字符
,而不是
因子
,因此
levels()
对它们不起作用。我已经编辑了答案,将
levels()
替换为
unique()
。它现在应该可以与character和factor列一起使用。谢谢@ramnath-这确实是一个非常优雅和简单的解决方案。不幸的是,当我将它应用于整个数据集时,这个家伙也会使我的计算机崩溃。我想我要回到我的R之前的策略,使用python处理我的数据(我迭代数据并将结果写入一个文件,这样计算机就不会翻转),然后使用R进行绘图功能。
foo
bar
有多大?它们包含多少级别?请检查我的编辑。它使用
data.table
进行
合并
,因此非常有效。你能检查一下这对你是否有效吗?如果这一步是瓶颈的话,我正试图找出一种有效的方法来
转换数据。使用datatable要快得多。我的
foo
bar
大约有55k和1.5M长。我还没有试过在全长数据框上进行转换,因为我认为可能会有一些有趣的事情发生在dables加入的方式上。data.table太棒了!结果表的dcast非常快,现在我可以专注于根据自己的心意进行强制转换/拆分/子集设置。谢谢你花时间给我展示这个方法。堆栈溢出社区给我留下了深刻的印象!谢谢@ramnath-这确实是一个非常优雅和简单的解决方案。不幸的是,当我将它应用于整个数据集时,这个家伙也会使我的计算机崩溃。我想我要回到我的R之前的策略,使用python处理我的数据(我迭代数据并将结果写入一个文件,这样计算机就不会翻转),然后使用R进行绘图功能。
foo
bar
有多大?它们包含多少级别?请检查我的编辑。它使用
data.table
进行
合并
,因此非常有效。你能检查一下这对你是否有效吗?如果这一步是瓶颈的话,我正试图找出一种有效的方法来
转换数据。使用datatable要快得多。我的
foo
bar
大约有55k和1.5M长。我还没有试过在全长数据框上进行转换,因为我认为可能会有一些有趣的事情发生在dables加入的方式上。data.table太棒了!结果表的dcast非常快,现在我可以专注于根据自己的心意进行强制转换/拆分/子集设置。谢谢你花时间给我展示这个方法。堆栈溢出社区给我留下了深刻的印象!
foo_dt <- data.table(foo, key = 'y')
bar_dt <- data.table(bar, key = 'y')
df1 <- bar_dt[foo_dt, nomatch = 0]