如何應用具有多個引數的自定義函式來回傳沒有 for 回圈的 N x M 資料幀?
例如:
mat1 <- data.frame(a = 1:5, b = -1)
vec1 <- 100:107
myfcn <- function(x, vals){
ans <- (x vals[1]) * vals[2]
return(ans)
}
df <- data.frame(matrix(nrow = length(mat1), ncol = length(vec1))) # pre-allocate
for (i in 1:length(vec1)){
for (j in 1:nrow(mat1)){
result <- myfcn(vec1[i], vals = c(mat1$a[j], mat1$b[j]))
df[j,i] <- result
}
}
print(df)
這將回傳所需的輸出矩陣:

如何跳過 for 回圈并使用某種應用函式來獲取上述輸出矩陣?
我試過sapply(vec1, myfcn, vals = c(mat1$a, mat1$b))了,但它回傳這個:

我試過outer(vec1, c(mat1$a, mat1$b), myfcn)了,但它回傳了這個:

uj5u.com熱心網友回復:
你可以簡單地這樣做:
result = sapply(vec1,\(v) (v mat1$a)*mat1$b)
如果要使用myfcn,請對其稍作改動:
myfcn <- function(x, v1,v2) (x v1)*v2
result = sapply(vec1,myfcn,v1=mat1$a, v2=mat1$b)
輸出:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] -101 -102 -103 -104 -105 -106 -107 -108
[2,] -102 -103 -104 -105 -106 -107 -108 -109
[3,] -103 -104 -105 -106 -107 -108 -109 -110
[4,] -104 -105 -106 -107 -108 -109 -110 -111
[5,] -105 -106 -107 -108 -109 -110 -111 -112
如果要轉換為上面同名的框架,添加以下內容:
setNames(as.data.frame(result), paste0("X",1:ncol(result)))
輸出:
X1 X2 X3 X4 X5 X6 X7 X8
1 -101 -102 -103 -104 -105 -106 -107 -108
2 -102 -103 -104 -105 -106 -107 -108 -109
3 -103 -104 -105 -106 -107 -108 -109 -110
4 -104 -105 -106 -107 -108 -109 -110 -111
5 -105 -106 -107 -108 -109 -110 -111 -112
uj5u.com熱心網友回復:
首先,您不需要雙for回圈來填充, R 是矢量化的,您可以每次通過回圈df將整個傳遞給函式。vec1
mat1 <- data.frame(a = 1:5, b = -1)
vec1 <- 100:107
myfcn <- function(x, vals){
ans <- (x vals[1]) * vals[2]
return(ans)
}
df <- as.data.frame(matrix(nrow = length(mat1), ncol = length(vec1))) # pre-allocate
for (j in 1:nrow(mat1)){
result <- myfcn(vec1, vals = c(mat1$a[j], mat1$b[j]))
df[j,] <- result
}
df
#> V1 V2 V3 V4 V5 V6 V7 V8
#> 1 -101 -102 -103 -104 -105 -106 -107 -108
#> 2 -102 -103 -104 -105 -106 -107 -108 -109
#> 3 -103 -104 -105 -106 -107 -108 -109 -110
#> 4 -104 -105 -106 -107 -108 -109 -110 -111
#> 5 -105 -106 -107 -108 -109 -110 -111 -112
使用reprex v2.0.2創建于 2022-10-10
現在有一個sapply回圈。您甚至不必預先分配空間,回圈會自行完成。
df2 <- t(sapply(1:nrow(mat1), \(j) myfcn(vec1, vals = c(mat1$a[j], mat1$b[j]))))
df2 <- as.data.frame(df2)
identical(df, df2)
#> [1] TRUE
使用reprex v2.0.2創建于 2022-10-10
另請注意,如果您需要表格資料結構但不是專門的 data.frame,則as.data.frame不需要最后一個。
uj5u.com熱心網友回復:
你在正確的路線上outer():
outer(mat1$a, vec1, ` `) * mat1$b
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] -101 -102 -103 -104 -105 -106 -107 -108
# [2,] -102 -103 -104 -105 -106 -107 -108 -109
# [3,] -103 -104 -105 -106 -107 -108 -109 -110
# [4,] -104 -105 -106 -107 -108 -109 -110 -111
# [5,] -105 -106 -107 -108 -109 -110 -111 -112
例如,如果mat1$bis -1:-5,這也將起作用 - 不僅僅是在它是常數的情況下。
uj5u.com熱心網友回復:
pmap在我看來是最優雅的解決方案。
在這種特殊情況下,有一個額外的步驟來創建具有相同長度的向量的輸入資料,但是應用陳述句很簡單df$result <- pmap_dbl(df, foo)
library(tidyverse)
foo <- function(x, a, b){
ans <- (x a) * b
return(ans)
}
# input data
df <- data.frame(a = 1:5, b = -1) %>% expand_grid(x = 100:107)
# pmap will used named arguments if the first argument has names
df$result <- pmap_dbl(df, foo)
# if argument has no names, will use them as ordered
df$result2 <- pmap_dbl(with(df, list(x, a, b)), foo)
print(df, n = Inf)
#> # A tibble: 40 × 5
#> a b x result result2
#> <int> <dbl> <int> <dbl> <dbl>
#> 1 1 -1 100 -101 -101
#> 2 1 -1 101 -102 -102
#> 3 1 -1 102 -103 -103
#> 4 1 -1 103 -104 -104
#> 5 1 -1 104 -105 -105
#> 6 1 -1 105 -106 -106
#> 7 1 -1 106 -107 -107
#> 8 1 -1 107 -108 -108
#> 9 2 -1 100 -102 -102
#> 10 2 -1 101 -103 -103
#> 11 2 -1 102 -104 -104
#> 12 2 -1 103 -105 -105
#> 13 2 -1 104 -106 -106
#> 14 2 -1 105 -107 -107
#> 15 2 -1 106 -108 -108
#> 16 2 -1 107 -109 -109
#> 17 3 -1 100 -103 -103
#> 18 3 -1 101 -104 -104
#> 19 3 -1 102 -105 -105
#> 20 3 -1 103 -106 -106
#> 21 3 -1 104 -107 -107
#> 22 3 -1 105 -108 -108
#> 23 3 -1 106 -109 -109
#> 24 3 -1 107 -110 -110
#> 25 4 -1 100 -104 -104
#> 26 4 -1 101 -105 -105
#> 27 4 -1 102 -106 -106
#> 28 4 -1 103 -107 -107
#> 29 4 -1 104 -108 -108
#> 30 4 -1 105 -109 -109
#> 31 4 -1 106 -110 -110
#> 32 4 -1 107 -111 -111
#> 33 5 -1 100 -105 -105
#> 34 5 -1 101 -106 -106
#> 35 5 -1 102 -107 -107
#> 36 5 -1 103 -108 -108
#> 37 5 -1 104 -109 -109
#> 38 5 -1 105 -110 -110
#> 39 5 -1 106 -111 -111
#> 40 5 -1 107 -112 -112
使用reprex v2.0.2創建于 2022-10-10
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/513415.html
標籤:r矩阵申请
