mapply в ddply - PullRequest
       21

mapply в ddply

3 голосов
/ 07 января 2012

примечание: это прямое продолжение этого предыдущего вопроса


У меня очень длинный фрейм данных, состоящий из двух столбцов, которые я использую в качестве аргументов для функции, которая найдет значение третьего столбца, используя 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

EDIT:



В свете ответа и комментариев я публикую ниже небольшой воспроизводимый пример - это один из ответов на предыдущий вопрос. Однако, как отмечают комментаторы ниже, ddply, вероятно, не тот путь. Я сейчас пытаюсь найти решение Рамната.

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

1 Ответ

4 голосов
/ 07 января 2012

ddply не то, что вы ищете здесь, ddply(df,.(1st), FUNCTION) больше похоже на:

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

То есть outdf состоит из FUNCTION, примененного к подмножествам df, определенным столбцом 1st.

В любом случае, я думаю, что ваша ошибка может быть из-за того, что у вас есть df вместо x в function(x) x$3rd<-mapply(myfunction,A=x$1st, B=df$second) (аргумент B)? Хотя трудно сказать без рабочего примера.

Что именно делает myfunction? Я думаю, что вам лучше всего ставить векторизация myfunction, чтобы вы могли просто сделать df$third <- myfunction( A=df$first, B=df$second ).

Например, если myfunction <- function(A,B) { A+B }, вместо выполнения mapply(myfunction,df$first,df$second) вы могли бы эквивалентно сделать myfunction(df$first,df$second) и вообще не нуждаться в mapply.

...