2013-08-01 2 views
2

스파 스 매트릭스에서 영이 아닌 이웃과의 거리를 계산하는 방법을 알리는 사람이 있습니까? 이렇게하는 이유는 크고 다차원적인 매트릭스에서 "구멍"을 확인하기 위해서입니다. 예를 들어매트릭스에서 0 이웃과의 거리를 얻으십시오.

:

f<-ceiling((runif(100,0,1))-.6) 
a <- matrix(f, ncol=10L, nrow=10L) 
rownames(a) = seq(1,10,1) 
colnames(a) = seq(1,10,1) 

가 나는 결과가 인으로 필요한 것은

> a 
    1 2 3 4 5 6 7 8 9 10 
1 0 0 0 0 1 0 0 1 1 0 
2 1 0 0 0 1 0 0 0 0 0 
3 0 1 1 0 1 1 0 0 1 1 
4 0 0 1 1 0 1 0 1 0 0 
5 0 0 0 1 0 1 0 0 0 1 
6 1 0 0 0*0*1 0 1 0 0 
7 0 1 1 1 1 1 1 0 1 0 
8 1 0 1 0 1 0 0 0 1 1 
9 1 1 1 0 0 0 0 0 0 0 
10 1 1 1 1 1 0 1 0 1 0 

수 :이 전 제로의 많은 일부 초 가득 10 × 10 행렬을 가정 해 봅시다 10x10 매트릭스 모든 4 가지 방향의 평균 거리 (각 치수에 대해 2 개)가 모든 영점에 적용됩니다.

예. 점 a[6,5]은 0이고 4 개의 이웃을 가지고 있습니다. 왼쪽으로의 거리는 5, 오른쪽의 거리는 1, 위로는 3, 아래로의 거리는 1입니다. 따라서 평균은 2.5입니다. 이웃이 존재하지 않으면 남은 이웃에 대해 평균을 계산해야합니다.

평상시처럼 제 첫 번째 아이디어는 모든 루프의 각 행렬 값을 찾고 거리를 반환하는 for 루프입니다. 그러나 이것은 당신이 which와 스파 스 R의 X의 C 형태로 변환 할 수 있습니다 매트릭스

+1

을, 나는 왼쪽까지의 거리를 생각 0이 아닌 4입니다. –

+0

적어도 10x10 범위를 암시 적으로 반복하려면 '적용'또는 '외부'와 같은 일부 기능이 필요하다고 생각합니다. –

+0

당연히 당신 말이 맞습니다, David –

답변

1

나는 그 문제를 많이 좋아! 여기에 해결책이 있습니다. 반드시 빠르지는 않지만 일을합니다. (우리가 만들어 여기

rev.list <- function(l) lapply(l, rev) 

v1 <- split(a, row(a)) # rows left to right 
v2 <- rev.list(v1)  # rows right to left 
v3 <- split(a, col(a)) # cols up to down 
v4 <- rev.list(v3)  # cols down to up 

과 기능을 적용의이 벡터의 네 지향 목록으로 행과 열을 분할하자, 여기에

a <- matrix(scan(textConnection(" 
    0 0 0 0 1 0 0 1 1 0 
    1 0 0 0 1 0 0 0 0 0 
    0 1 1 0 1 1 0 0 1 1 
    0 0 1 1 0 1 0 1 0 0 
    0 0 0 1 0 1 0 0 0 1 
    1 0 0 0 0 1 0 1 0 0 
    0 1 1 1 1 1 1 0 1 0 
    1 0 1 0 1 0 0 0 1 1 
    1 1 1 0 0 0 0 0 0 0 
    1 1 1 1 1 0 1 0 1 0 
")), 10, 10, byrow = TRUE) 

:

우선의이 데이터를 다시 보자

dir.dist <- function(v) { 
    out <- seq_along(v) - cummax(seq_along(v) * v) 
    out[seq_len(match(1, v) - 1)] <- NA 
    out 
} 

dist1.list <- lapply(v1, dir.dist) # dist to closest on left 
dist2.list <- lapply(v2, dir.dist) # dist to closest on right 
dist3.list <- lapply(v3, dir.dist) # dist to closest up 
dist4.list <- lapply(v4, dir.dist) # dist to closest dn 
)를 계산하기 위해 : https://stackoverflow.com/a/17929557/1201032에서 영감을 얻었습니다. ,의는 pmean https://stackoverflow.com/a/13123779/1201032에서 영감 기능을 사용하여 수단 계산하자 마지막으로

nr <- nrow(a) 
nc <- ncol(a) 

list.to.mat <- function(l, revert = FALSE, byrow = FALSE, 
          nrow = nr, ncol = nc) { 
    x <- unlist(if (revert) rev.list(l) else l) 
    matrix(x, nrow, ncol, byrow) 
} 

m1 <- list.to.mat(dist1.list, revert = FALSE, byrow = TRUE) 
m2 <- list.to.mat(dist2.list, revert = TRUE, byrow = TRUE) 
m3 <- list.to.mat(dist3.list, revert = FALSE, byrow = FALSE) 
m4 <- list.to.mat(dist4.list, revert = TRUE, byrow = FALSE) 

:

지금의 네 행렬에 다시 모든 것을 만들어 보자 당신의 예에서

pmean <- function(..., na.rm = FALSE) { 
    dat <- do.call(cbind, list(...)) 
    res <- rowMeans(dat, na.rm = na.rm) 
    idx_na <- !rowSums(!is.na(dat)) 
    res[idx_na] <- NA 
    res 
} 

final <- matrix(pmean(as.vector(m1), 
         as.vector(m2), 
         as.vector(m3), 
         as.vector(m4), na.rm = TRUE), nr, nc) 

final 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
# [1,] 2.50 2.50 2.00 2.00 0.00 1.67 3.00 0.0 0.00 1.50 
# [2,] 0.00 1.67 1.67 2.00 0.00 1.00 3.50 2.0 2.00 3.00 
# [3,] 1.67 0.00 0.00 1.00 0.00 0.00 2.33 1.5 0.00 0.00 
# [4,] 2.00 1.67 0.00 0.00 1.50 0.00 1.67 0.0 1.67 1.33 
# [5,] 2.33 2.00 1.33 0.00 1.50 0.00 2.00 1.5 2.00 0.00 
# [6,] 0.00 2.25 2.00 1.75 *2.25* 0.00 1.00 0.0 1.67 1.67 
# [7,] 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.0 0.00 1.33 
# [8,] 0.00 1.00 0.00 1.25 0.00 1.67 1.75 2.0 0.00 0.00 
# [9,] 0.00 0.00 0.00 1.33 1.33 2.50 2.33 4.0 2.67 4.00 
# [10,] 0.00 0.00 0.00 0.00 0.00 1.67 0.00 2.0 0.00 1.50 
+0

이것은 인상적으로 보입니다, 당신의 노력에 감사드립니다, 나는 그것을 통해 갈 것입니다. 내 원래의 문제에 대해 작동하는지 알려주십시오. –

0

... 그것을 할 수있는 멍청한 방법이 있어야합니다

rc <- which(a>0, arr.ind=TRUE) 
rc[rc[,1] == 6, 2] # 1, 6,8 candidates for "row-neighbors" 
rc[rc[,2] == 5, 1] # 1,2,3, 7,8,10 col-neighbors 
+0

"이웃에 대한 후보자는 좋은 중간 결과입니다. 나는 이것도 시도 할 것입니다 .DWin! –

관련 문제