2016-10-19 3 views
5

사이트 및 시간 이벤트 행렬을 생성하려고합니다. 제 경우에는 이벤트가 발생하면 ("1") 영구적이어서 "0"으로 돌아갈 수 없습니다. 한 열의 셀이 "1"이면 오른쪽의 후속 열에서 인접한 셀에 "1"을 채우려고합니다 (예제보기 참조).R dplyr : 열의 특정 값을 찾은 다음 후속 열의 오른쪽 셀을 해당 값으로 바꿉니다.

site <- c('A','B','C','D','E','F','G') #site 
time <- c(0,1,4,0,3,2,0) # time in which even occured 
event <- c(0,1,1,0,1,1,0) # did a event occur 
data <- data.frame(site, time, event) 

site.time.matrix <- cast(data, site~time) 

# This is the output  # This is the desired output 
#site 0 1 2 3 4  #site 0 1 2 3 4 
# A 0 NA NA NA NA  # A 0 0 0 0 0 
# B NA 1 NA NA NA  # B 0 1 1 1 1 
# C NA NA NA NA 1  # C 0 0 0 0 1 
# D 0 NA NA NA NA  # D 0 0 0 0 0 
# E NA NA NA 1 NA  # E 0 0 0 1 1 
# F NA NA 1 NA NA  # F 0 0 1 1 1 
# G 0 NA NA NA NA  # G 0 0 0 0 0 

예를 들어 dplyr을 사용하여 유망한 코드를 발견했습니다. (Replacing more than one elements with replace function 또는 Apply function to each column in a data frame observing each columns existing data type) 값을 대체합니다. 그러나 후속 열의 인수에서 인접 셀을 지정하는 방법이 확실하지 않습니다.

이 질문에 불분명하면 사과드립니다. StackOverflow에 대한 첫 번째 게시물입니다.

감사합니다.

답변

3

첫 번째 사용자 게시물이 상세하고 재현성 있고 흥미로운 +1 인 경우 기쁩니다.

na.locf으로 zoo 패키지에서 당신이 할 수있는, • base R 접근 방식은 apply를 사용

library(reshape) # for cast function 
library(zoo) #for na.locf function short for if NA, last observation carrried forward, ?na.locf 

site <- c('A','B','C','D','E','F','G') #site 
time <- c(0,1,4,0,3,2,0) # time in which even occured 
event <- c(0,1,1,0,1,1,0) # did a event occur 
data <- data.frame(site, time, event) 

site.time.matrix <- reshape::cast(data, site~time) 

site.time.matrix.fill <- site.time.matrix 


# Transpose the matrix excluding first column, carry forward last observation and 
# transpose again to return to original matrix structure 

site.time.matrix.fill[,-1] <- t(na.locf(t(site.time.matrix.fill[,-1]))) 

site.time.matrix.fill[is.na(site.time.matrix.fill)] <- 0 

site.time.matrix.fill 

# site 0 1 2 3 4 
#1 A 0 0 0 0 0 
#2 B 0 1 1 1 1 
#3 C 0 0 0 0 1 
#4 D 0 0 0 0 0 
#5 E 0 0 0 1 1 
#6 F 0 0 1 1 1 
#7 G 0 0 0 0 0 
+0

감사합니다. Osssan, 나는 '동물원'패키지에 대해 들어 본 적이 없으며, 이것이 내가 필요한 것입니다. 이것들은 모두 정말 좋은 답변입니다, 나는 당신이 똑같은 일을 할 수있는 모든 다른 방법을 보는 것을 좋아합니다. :) – CarlaBirdy

1

.

기본적으로 모든 행에 대해 1이 들어있는 요소를 찾고 왼쪽에있는 모든 요소에 0을 할당하고 오른쪽에 모든 요소에 1을 할당하려고합니다.

t(apply(site.time.matrix, 1, function(x) { 
     temp = if(any(x == 1, na.rm = T)) which(x==1)-1 else length(x) 
     x[temp:length(x)] <- 1 
     x[0:temp] <- 0 
     x 
})) 


# 0 1 2 3 4 
#A 0 0 0 0 0 
#B 0 1 1 1 1 
#C 0 0 0 0 1 
#D 0 0 0 0 0 
#E 0 0 0 1 1 
#F 0 0 1 1 1 
#G 0 0 0 0 0 
+1

당신의 대답 Ronak에 감사드립니다. 나는 당신이 똑같은 일을 할 수있는 모든 다른 방법들을 보는 것을 좋아합니다. 나는 apply 함수를 사용하는 데 많은 경험이 없기 때문에, 개선 할 것이기를 바래서이 것을 도와 주신 것에 감사드립니다. – CarlaBirdy

+0

@CarlaBirdy 큰 도움이되었다는 것을 알게 되서 굉장합니다. 여기에서 대답 중 하나를 수락 할 수 있습니다. 확인 [이] (http://stackoverflow.com/help/someone-answers) –

0

여기에는 두 번째 기본 R 방법 (재 형성 제외)이 있습니다. 여기에는 applycummax (누적 최대 값)이 사용됩니다. 각 사이트에 대해 하나의 이벤트 만 발생하면 cummaxcumsum으로 바꾸면 동일한 결과가 반환됩니다. 제 (cast와) 재편도 기본 R reshape 기능을 수행하지만, 당신도 할 수 있습니다 다시 순서 :

# reshape the data 
temp <- cast(data, site~time) 

# construct matrix of 0s and 1s 
myMat <- as.matrix(temp[-1]) 
myMat[is.na(myMat)] <- 0 

# expand 1s to the right when they appear 
myMat <- t(apply(myMat, 1, cummax)) 

# add row and column names 
dimnames(myMat) <- list(levels(temp$site), seq_len(ncol(myMat))-1) 

myMat 
    0 1 2 3 4 
A 0 0 0 0 0 
B 0 1 1 1 1 
C 0 0 0 0 1 
D 0 0 0 0 0 
E 0 0 0 1 1 
F 0 0 1 1 1 
G 0 0 0 0 0 

주를 반환 변수. 예를 들어,

# reshape data 
temp <- reshape(data, direction="wide", idvar="site") 
# reorder variables 
temp <- temp[c("site", sort(names(temp)[-1]))] 

은 예상 데이터 프레임을 생성합니다.

site event.0 event.1 event.2 event.3 event.4 
1 A  0  NA  NA  NA  NA 
2 B  NA  1  NA  NA  NA 
3 C  NA  NA  NA  NA  1 
4 D  0  NA  NA  NA  NA 
5 E  NA  NA  NA  1  NA 
6 F  NA  NA  1  NA  NA 
7 G  0  NA  NA  NA  NA 
+1

@로 나크 샤 감사. 나는'개작 '의 결과를 충분히 확인하지 못했습니다. – lmo

+0

나는 똑같은 일을 할 수있는 모든 다른 방법을 보는 것을 좋아합니다. 답장을 보내 주셔서 감사합니다. 오늘 모든 다른 유형의 코드를 살펴 보겠습니다. :) – CarlaBirdy