我創建了一個資料框和一個函式,我想在串列物件的元素中運行它。我想從每個串列元素的函式結果中輸出一個矩陣。
例如對于我想得到這個輸出的每個元素:
| d1 | d2 | d3 | |
|---|---|---|---|
| d1 | ED(d1,d1) | ED(d2, d1) | ED(d3, d1) |
| d2 | ED(d2, d1) | ED(d2, d2) | ED(d3, d2) |
| d3 | ED(d3, d1) | ED(d2, d3) | ED(d3, d3) |
我創建的函式在哪里ED(),引數是串列元素中包含的資料框中的列。
我知道我會用它lapply來獲得這個輸出,但我不確定如何得到它。
set.seed(123)
d1 = sample.int(50, 27)
d2 = sample.int(50, 27)
d3 = sample.int(50, 27)
year <- c(1990:1998)
site <- c(rep("a", 9), rep("b", 9), rep("c", 9))
ED = function(x,y){
#x and y are vectors of spp abundances
#they must be the same length!
if(length(x)!=length(y)) stop("Bad abundances!")
out = sqrt(sum((x-y)^2))
out
}
df <- data.frame(site, year, d1 = d1, d2 = d2, d3 = d3)
l <- split(df, df$site)
uj5u.com熱心網友回復:
這里有三種方式。
前兩個使用輔助函式以使代碼更具可讀性。為了計算所有ED向量之間的所有距離,需要一個雙sapply回圈。
1.split/lapply
set.seed(123)
d1 = sample.int(50, 27)
d2 = sample.int(50, 27)
d3 = sample.int(50, 27)
year <- 1990:1998
site <- c(rep("a", 9), rep("b", 9), rep("c", 9))
ED = function(x,y){
#x and y are vectors of spp abundances
#they must be the same length!
if(length(x)!=length(y)) stop("Bad abundances!")
out = sqrt(sum((x-y)^2))
out
}
df <- data.frame(site, year, d1 = d1, d2 = d2, d3 = d3)
aux <- function(x) {
x <- as.list(x)
sapply(x, \(.x) sapply(x, ED, y = .x))
}
l <- split(df[-2], df$site)
lapply(l, \(x) aux(x[-1]))
#> $a
#> d1 d2 d3
#> d1 0.00000 67.59438 74.17547
#> d2 67.59438 0.00000 55.79426
#> d3 74.17547 55.79426 0.00000
#>
#> $b
#> d1 d2 d3
#> d1 0.00000 64.09368 66.21178
#> d2 64.09368 0.00000 52.61179
#> d3 66.21178 52.61179 0.00000
#>
#> $c
#> d1 d2 d3
#> d1 0.00000 52.99057 53.45091
#> d2 52.99057 0.00000 42.17819
#> d3 53.45091 42.17819 0.00000
使用reprex v2.0.2創建于 2022-10-15
2.拆分并應用by
by無需先拆分資料集。
by(df, df$site, \(subdf) aux(subdf[-(1:2)]))
#> df$site: a
#> d1 d2 d3
#> d1 0.00000 67.59438 74.17547
#> d2 67.59438 0.00000 55.79426
#> d3 74.17547 55.79426 0.00000
#> ------------------------------------------------------------
#> df$site: b
#> d1 d2 d3
#> d1 0.00000 64.09368 66.21178
#> d2 64.09368 0.00000 52.61179
#> d3 66.21178 52.61179 0.00000
#> ------------------------------------------------------------
#> df$site: c
#> d1 d2 d3
#> d1 0.00000 52.99057 53.45091
#> d2 52.99057 0.00000 42.17819
#> d3 53.45091 42.17819 0.00000
使用reprex v2.0.2創建于 2022-10-15
3.by和dist
該函式ED計算兩個向量之間的歐幾里得距離。使用 R 的內置函式dist,不需要EDnor aux。
by(df, df$site, \(subdf) dist(t(subdf[-(1:2)]), diag = TRUE, upper = TRUE))
#> df$site: a
#> d1 d2 d3
#> d1 0.00000 67.59438 74.17547
#> d2 67.59438 0.00000 55.79426
#> d3 74.17547 55.79426 0.00000
#> ------------------------------------------------------------
#> df$site: b
#> d1 d2 d3
#> d1 0.00000 64.09368 66.21178
#> d2 64.09368 0.00000 52.61179
#> d3 66.21178 52.61179 0.00000
#> ------------------------------------------------------------
#> df$site: c
#> d1 d2 d3
#> d1 0.00000 52.99057 53.45091
#> d2 52.99057 0.00000 42.17819
#> d3 53.45091 42.17819 0.00000
使用reprex v2.0.2創建于 2022-10-15
uj5u.com熱心網友回復:
您可以進行外部操作,并且由于引數是列,因此您必須對 xy 進行矢量化(我使用 mapply 進行)
v <- c("d1","d2","d3")
lapply(l, function(li) {
outer(v,v, function(x,y) {
mapply(x,y, FUN = function(xi,yi)
ED(li[,xi],li[,yi]), SIMPLIFY = T)
})
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/515911.html
標籤:r列表矩阵
