#r
#r
Вопрос:
Есть ли какая-то функция в R в виде:
crossApply(v1, v2, func)
это имеет ту же функциональность, что и:
ret = c()
i = 1
for (e1 in v1) {
for (e2 in v2) {
ret[i] <- func(e1,e2)
i <- i 1
}
}
return(ret)
Заранее спасибо.
Ответ №1:
Я думаю, вы можете искать outer
, что не совсем то, что делает ваш код, но это близко. В частности, outer
Вернет матрицу (т. Е. Внешнее произведение) или каждую комбинацию элементов ее первых двух аргументов.
Вероятно, вы захотите сохранить результат, а затем извлечь нижний треугольник в виде вектора. Может быть, что-то вроде этого:
rs <- outer(1:4,-(5:7)," ")
rs[lower.tri(rs,diag = TRUE)]
[1] -4 -3 -2 -1 -4 -3 -2 -4 -3
Комментарии:
1. Спасибо! Как я могу определить пользовательскую функцию для использования во внешнем? Не могли бы вы привести пример? Я продолжаю получать ошибки при попытке этого, и мои сообщения об ошибках на китайском языке, поэтому, я думаю, их публикация мало поможет.
2. @SpiritZhang:
emulatesum<-function(x,y) return(x y)
как функция, а затемrs <- outer(1:4,-(5:7),"emulatesum")
. Кстати: я настоятельно рекомендую использовать R на английском языке, особенно для сообщений об ошибках: их поиск в Google намного проще, когда они у вас есть на английском…3. @NickSabbe: Спасибо, Ник! Я не обращал особого внимания на язык, когда устанавливал R. Поскольку я в Китае, я думаю, именно поэтому R сделал китайский язык языком по умолчанию.
Ответ №2:
Пример
func <- function(x,y) {sqrt(x^2 y^2)}
v1 <- c(1,3,5)
v2 <- c(0,-4,-12)
ret <- outer(v1,v2,"func")
И тогда у вас есть
> ret
[,1] [,2] [,3]
[1,] 1 4.123106 12.04159
[2,] 3 5.000000 12.36932
[3,] 5 6.403124 13.00000
или, если вы хотите, чтобы именно то, что создавали ваши циклы for
> as.vector(t(ret))
[1] 1.000000 4.123106 12.041595 3.000000 5.000000 12.369317 5.000000
[8] 6.403124 13.000000
Ответ №3:
Это довольно легко сделать с do.call
помощью и expand.grid
:
x <- seq(0,10, length.out=10)
> y <- seq(-1,1, length.out=5)
> d1 <- expand.grid(x=x, y=y)
> do.call("*", d1)
[1] 0.0000000 -1.1111111 -2.2222222 -3.3333333 -4.4444444
[6] -5.5555556 -6.6666667 -7.7777778 -8.8888889 -10.0000000
[11] 0.0000000 -0.5555556 -1.1111111 -1.6666667 -2.2222222
[16] -2.7777778 -3.3333333 -3.8888889 -4.4444444 -5.0000000
[21] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
[26] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
[31] 0.0000000 0.5555556 1.1111111 1.6666667 2.2222222
[36] 2.7777778 3.3333333 3.8888889 4.4444444 5.0000000
[41] 0.0000000 1.1111111 2.2222222 3.3333333 4.4444444
[46] 5.5555556 6.6666667 7.7777778 8.8888889 10.0000000
Комментарии:
1. Отлично, но обратите внимание, что
do.call
в этом случае может работать только векторизованная функция. например, do.call(означает, d1) завершается с ошибкой.2. так что, возможно, так и должно быть
do.call("mapply", c(fun, d1))
.3. Интересная идея. Кажется, это связано с
do.call(expand.grid(.))
тем, чтоVectorize
делает с.sapply