2017-10-02 5 views
1

R 벡터화의 이점을 활용하여보다 효율적인 방식으로 원하는 작업을 수행하는 방법을 이해하는 데 어려움이 있습니다.R 벡터화 기능 구현

간단히 말해 각 행에 대해 현재 행의 두 번째 열 ($ start)을 이전 및 다음 행의 $ start와 비교합니다 (모든 값은 정수입니다.이 값을 prev_dist 및 next_dist라고 부릅시다). 다음으로, 현재 행의 4 번째 열 ($ condition)과 그 이전의 $ 조건 또는 5 개의 다음 $ 조건을 인쇄합니다 (즉, 현재 행의 $ start에 가장 근접한 이전 또는 다음 행의 $ 시작).

weather 146 17 Rainy 
weather 147 17 Rainy 
weather 163 16 Sunny 
weather 173 15 Sunny 
weather 176 15 Rainy 
weather 197 12 Rainy  

나는 내 출력 (A dataframe에서)과 같이되고 싶어 : 나는 아래 함수를 작성하는 것을 시도했다

Rainy Rainy Sunny Sunny Sunny Rainy 
Rainy Sunny Sunny Sunny Rainy Rainy 
etc. 

하지만,이 기능은 대형, 시뮬레이션 데이터 세트 영원히 실행됩니다.

누군가이 경우 벡터화를 구현하는 방법을 이해하는 데 도움이 될 수 있습니까?

buildMatrix <- function(input){ 
len <- nrow(input)-6 
sequence_matrix <- data.frame() 

for(line in 6:len){ 

    start <- input[line,]$start 
    prev_start <- input[line-1,]$start 
    next_start <- input[line+1,]$start 
    prev_dist <- abs(start-prev_start) 
    next_dist <- abs(start-next_start) 
    current_seq <- input[line,]$condition 

    if(prev_dist < next_dist || prev_dist == next_dist){ 
    for(i in 1:5){ 
     prev_seq <- input[line-i,]$condition 
     current_seq <- c(current_seq, prev_seq)} 
    } else if(prev_dist > next_dist){ 
    for(i in 1:5){ 
     next_seq <- input[line+i,]$condition 
     current_seq <- c(current_seq, next_seq)} 
    } 
    sequence_matrix <- rbind(sequence_matrix, current_seq) 
    } 
colnames(sequence_matrix) <- c("p0", "p1", "p2", "p3", "p4", "p5") 
sequence_matrix 
} 

수정 된 코드 : 당신의 이점에

library(dplyr) 
islessthan <- abs(df$V2-lead(df$V2)) < abs(df$V2-lag(df$V2)) 

ans <- lapply(seq_along(islessthan), function(i) if (is.na(islessthan[i])) { 
    NA 
} else if(islessthan[i]==FALSE) { 
c(df$V4[i], head(lag(df$V4, pmax(6-i, 0)), 5)) 
} else { 
c(df$V4[i], head(lead(df$V4, i), 5)) 
}) 
+0

대신'$ V2' 등 - 열에 유익한 이름을주지 않으시겠습니까? 그런 다음,'prev_start'와'next_start' (경우에 따라 마지막 또는 마지막 행에 'NA'가 채워짐)에 대한 새로운 열을 생성 할 수 있습니다. 이것은 한 줄짜리 루프가없는 문장으로 할 수 있습니다. 일단 그 단계에 도달하면 문제는 훨씬 쉬워 질 것입니다. –

+0

이름 지정에 대해 포인트가 찍혔습니다. 위의 수정 된 코드와 같은 것을 의미 했습니까 (제 질문을 편집 했습니까?)? – kaka01

+0

내가 염두에 두었던 것은'df $ prev_start <- c (NA, head (df $ start, -1))'와'df $ next_start <- c (tail (df $ start, -1), NA)',''dplyr'' 기반의 해결책이 더 바람직 할 것이다. –

답변

3

사용 dplyr::lead/lag 기능

귀하의 데이터

df <- read.table(text="weather 146 17 Rainy 
weather 147 17 Rainy 
weather 163 16 Sunny 
weather 173 15 Sunny 
weather 176 15 Rainy 
weather 197 12 Rainy", header=FALSE, stringsAsFactors=F) 

각 행 (0 행)를 가지고 있는지 확인

+1-row < -1-row

library(dplyr) 
islessthan <- lead(df$V2) < lag(df$V2) 
# [1] NA FALSE FALSE FALSE FALSE NA 

lapply을 사용하여 위에서 작성한 논리 벡터와 데이터 프레임을 반복합니다. 행 is.na(row) == TRUENA을 반환합니다. 행 islessthan == FALSE0-row + +5-rows of column V4을 반환합니다. 행 어디 islessthan == TRUE 당신이 가장자리의 경우 (행 1 및 행-N)를 처리하는 방법을 지정하지 않은 -5-rows of column V4 + 0-row

ans <- lapply(seq_along(islessthan), function(i) if (is.na(islessthan[i])) { 
            NA 
           } else if(islessthan[i]==FALSE) { 
            c(df$V4[i], head(lead(df$V4, i), 6)) 
           } else { 
            c(head(lag(df$V4, 6-i), 6)) 
           }) 

출력

# [[1]] 
# [1] NA 

# [[2]] 
# [1] "Rainy" "Sunny" "Sunny" "Rainy" "Rainy" NA  NA  

# [[3]] 
# [1] "Sunny" "Sunny" "Rainy" "Rainy" NA  NA  NA  

# [[4]] 
# [1] "Sunny" "Rainy" "Rainy" NA  NA  NA  NA  

# [[5]] 
# [1] "Rainy" "Rainy" NA  NA  NA  NA  NA  

# [[6]] 
# [1] NA 

주를 반환하고됩니다 예를 들어 전체 벡터를 반환하기에 충분한 관찰이 없으므로 NA이 필러로 출력에 나타납니다.

+0

답변 해 주셔서 감사합니다. 한 가지는 궁금 해서요. dplyr의 기능은 여전히 ​​줄의 순서를 유지합니까? 아니면 주문에 무관심합니까? – kaka01

+0

짧은 답변은 주문을 보존한다는 것입니다. 'dplyr :: lead'는 데이터의 값을'N '만큼 앞당길 것이므로, 인덱스 N은 인덱스 1이됩니다.'dplyr :: lag'은 그 반대입니다. – CPak

+0

내 코드를 원하는대로 수정했습니다 (단지 $ V2 비교 대신 $ V2s의 차이점 비교) : islessthan <- abs (df $ V2-lead (df $ V2)) kaka01