results - summation in r




행렬을 계산하기 위해 R에서 여러 for-loops 사용하지 않기 (4)

따라서지도 질문에 답하기 위해 가짜 데이터를 생성하는 과정에서 다음과 같은 내용을 작성했습니다.

# Generate some fake data
lat <- seq(-90, 90, by = 5)
lon <- seq(-180, 180, by = 10)
phi <- matrix(0, nrow = length(lat), ncol = length(lon))
i <- 1
for (l1 in lat) {
    j <- 1
    for (l2 in lon) {
        phi[i, j] <- (sin(pi * l1 / 180) * cos(pi * l2 / 180))^2
        j <- j+1
    }
    i <- i+1
}
phi <- 1500*phi + 4500  # scale it properly

이제 분명히 두 개의 중심 for-loops는 내가 원하는만큼 R'ish가 아닙니다. 내가 할 일을해야 할 것 같아 보이지만, 슬프게도 목록을 반환하고, 내가 원하는 것을 실제로하지는 않습니다. 다른 적용은 옳은 일을하는 것 같지 않습니다.

내가 여기서 무엇을 놓치고 있니?


v * u ^ T를 통해 수행 할 수있는 요소 별 두 벡터를 곱하기 만하면 선형 대수가 응용 프로그램에서 더 간단해질 수 있습니다. R에서 행렬 곱셈은 %*% 입니다.

lat <- seq(-90, 90, by = 5)
lon <- seq(-180, 180, by = 10)

l1 <- sin(pi * lat / 180) 
l2 <- s(pi * lon/ 180)

# compute the matrix
phi <- as.matrix(l1)%*%t(as.matrix(l2))
# square each element of the matrix
phi <- phi^2
# scale properly
# square each element of the matrix
phi <- 1500*phi + 4500  

너는 outer 을 사용할 수있다.

   x = outer(lat, lon, FUN = function(x,y) {(sin(pi * x/180) * cos(pi * y /180))^2})
    identical(x * 1500 + 4500, phi)
# [1] TRUE

NBATrends의 대답은 다른 솔루션보다 빠릅니다. 여기에 몇 가지 벤치 마크

library(microbenchmark) 
microbenchmark(within(df, {
  phi <- (sin(pi * lat / 180) * cos(pi * lon / 180))^2
  phi <- 1500*phi + 4500
}), 1500 * tcrossprod(sin(pi * lat / 180), cos(pi * lon / 180))^2 + 4500, outer(lat, lon, FUN = function(x,y) {(sin(pi * x/180) * cos(pi * y /180))^2}),
((as.matrix(l1)%*%t(as.matrix(l2)))^2) * 1500 + 4500)
Unit: microseconds
                                                                                              expr     min       lq      mean   median       uq     max neval
 within(df, {     phi <- (sin(pi * lat/180) * cos(pi * lon/180))^2     phi <- 1500 * phi + 4500 }) 255.670 262.0095 270.50948 266.6880 277.7060 385.467   100
                                  1500 * tcrossprod(sin(pi * lat/180), cos(pi * lon/180))^2 + 4500  11.471  12.3770  22.30177  12.9805  13.5850 868.130   100
               outer(lat, lon, FUN = function(x, y) {     (sin(pi * x/180) * cos(pi * y/180))^2 }) 137.645 139.7590 144.39520 141.5700 145.1925 179.905   100
                                            ((as.matrix(l1) %*% t(as.matrix(l2)))^2) * 1500 + 4500  16.301  17.6595  20.20390  19.6215  20.5270  80.294   100

행렬 대수를 사용해야합니다. 적용 패밀리의 모든 기능을 사용할 필요가 없습니다.

lat <- seq(-90, 90, by = 5)
lon <- seq(-180, 180, by = 10)
1500 * tcrossprod(sin(pi * lat / 180), cos(pi * lon / 180))^2 + 4500

sapply() 사용하지만 outer() 솔루션을 선호합니다.

#using sapply
phi_1 <- 
  t(
    sapply(lat, function(l1)
      sapply(lon, function(l2)(sin(pi * l1 / 180) * cos(pi * l2 / 180))^2))
  ) * 1500 + 4500

#compare result
identical(phi_1, phi)
# [1] TRUE




mapply