mapply在ddply中的应用

3

注意:这是对上一个问题的直接跟进。


我有一个非常长的数据框,由两列组成,我正在将它们用作函数的参数,使用mapply查找第三列的值,如下所示:

df$3rd <- mapply(myfunction, A=df$1st, B=df$2nd)

myfunction有参数A和B时。虽然这对于小数据集非常有效,但对于大数据集则会停滞,因此我认为解决问题的好方法是使用ddply应用此函数。我不知道ddply是否是解决这个问题的最佳方法,但我也遇到了一些语法问题。所以任何建议都将不胜感激。

这是我正在尝试的:

> df$3rd <- ddply(df, .(1st), function(x) x$3rd <-
> mapply(myfunction, A=x$1st, B=df$second))

这是我收到的错误信息:

Error in `$<-.data.frame`(`*tmp*`, "n", value = c(1L, 1L, 1L, 1L, 1L,  : 
  replacement has 112 rows, data has 16

编辑:



鉴于答案和评论,我在下面发布了一个小的可重现示例-它是上一个问题的答案之一。但是,如下面的评论者所指出的那样,ddply可能不是正确的方法。我现在正在尝试Ramnath的解决方案。

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'))

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)))

# 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

2
一般来说,plyr函数是为了方便而存在的(方便的语法),apply函数族通常在时间紧迫时表现更好。介意提供一个小的可重复示例吗? - Roman Luštrik
1
@zach,看看我对你之前问题的解决方案。它不需要使用mapplyexpand.grid函数。 - Ramnath
1个回答

4

ddply在这里并不适用,ddply(df,.(1st), FUNCTION)更加合适:

for each val in unique(df$1st)
    outdf[nrow(outdf)+1,] = FUNCTION( df[df$1st==val] )

那就是说,它使得 outdf 由应用于由 1st 列决定的 df 子集的 FUNCTION 组成。
无论如何,我认为你的错误可能是因为在 function(x) x$3rd<-mapply(myfunction,A=x$1st, B=df$second)B 参数)中使用了 df 而不是 x。虽然没有一个工作示例很难确定。 myfunction 究竟是做什么的?我认为你最好的选择是将 myfunction 向量化,这样你就可以只需执行 df$third <- myfunction( A=df$first, B=df$second )
例如,如果 myfunction <- function(A,B) { A+B },那么你可以等效地执行 myfunction(df$first,df$second) 而且甚至根本不需要 mapply。

谢谢 @mathematical.coffee。我认为你是对的 - ddply 不会带来性能提升,并且向量化我的函数是一个好主意。然而,我的函数作为查找另外两个数据框中的值的工具 - 请参见上面和之前的问题 - 因此无法进行向量化处理。我想我会回到之前的策略,即在python中处理我的数据,并使用R分析结果表。 - zach
@Zach。在之前的问题的评论中,你发现了data.table。它对这个问题也适用吗? - Matt Dowle
@MatthewDowle。这可能适用于此案例,但data.table可以避免这种需要。这个问题旨在澄清先前问题的解决方案之一遇到的问题。Ramnath的data.table解决方案足够快且占用的内存较少,因此我可以直接使用他的解决方案而不必担心这个问题。如果您想知道是否可以向data.table传递多个参数,则我不确定,但是您肯定可以将其传递给连续的函数。此外-data.table的行为与data.frame不同,因此请仔细检查结果,直到您确定已经正确。 - zach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接