2012-02-14 4 views
0

R에 중첩 for 루프를 작성하려고하지만 문제가 발생합니다. 나는 가능한 한 많이 연구했지만 필요한 도움을 찾지 못했습니다. 나는 R에 상당히 익숙하다. 그러므로이 루핑에 대한 조언이나, 더 간단하고 우아한 방법이 있다면 좋을 것이다.R의 중첩 루프 : 열 다음 행

나는 많은 많은 위치에 대한 매일 온도의 파일을 생성 한 (내가 그들에게 사이트를 부를 것이다), 그리고 파일 열은 다음과 같이 설정되어 있습니다 :

년 월 일 unix_time site_a site_b site_c site_d ... on and on

각 사이트 내 (각 열 내) 온도 값을 살펴보고 해당 열의 범위에 해당하는 숫자 (생리 속도)로 새 열 (또는 새 데이터 프레임)을 만들고 싶습니다. 온도. (예 : 6.25도 미만의 온도는 -1.33, 6.25와 8.75 사이의 온도는 0.99의 비율 등). 단일 데이터 열에 대해이 작업을 수행하는 루프를 만들었습니다. 예를 들어 :

for(i in 1:dim(data)[1]){
if (data$point_a[i]<6.25) data$rate_point_a[i]<--1.33 else
if (data$point_a[i]>=6.25 && data$point_a[i]<8.75) data$rate_point_a[i]<-0.99 else
if (data$point_a[i]>=8.75 && data$point_a[i]<11.25) data$rate_point_a[i]<-3.31 else
if (data$point_a[i]>=11.25 && data$point_a[i]<13.75) data$rate_point_a[i]<-2.56 else
if (data$point_a[i]>=13.75 && data$point_a[i]<16.25) data$rate_point_a[i]<-1.81 else
if (data$point_a[i]>=16.25 && data$point_a[i]<18.75) data$rate_point_a[i]<-2.78 else
if (data$point_a[i]>=18.75 && data$point_a[i]<21.25) data$rate_point_a[i]<-3.75 else
if (data$point_a[i]>=21.25 && data$point_a[i]<23.75) data$rate_point_a[i]<-1.98 else
if (data$point_a[i]>=23.75 && data$point_a[i]<26.25) data$rate_point_a[i]<-0.21
}

위의 코드는 나에게 내 생리적 요금이있다 "rate_site_a"라는 새 열을 제공합니다. 내가 겪고있는 문제는이 루프를 모든 루프를 통과하는 다른 루프에 중첩시키는 것입니다. 나는 다음과 같은 것들을 시도 :

for (i in 1:ncol(data)){ 

#for each row in that column 
for (s in 1:length(data)){ 

    if ([i]<6.25) rate1[s]<--1.33 else ... 

내가 만드는 방법을 알고하지 않는 생각을 문 올바른 장소를 참조하십시오 "다른이 경우". 기존 데이터 프레임에 "비율"열을 추가 할 수 없다는 것을 알고 있습니다. 루프를 통과 할 때 ncol이 증가하므로 다른 데이터 프레임에 추가해야합니다 (단, 이것이 내 것이 아닙니다. 주요 문제). 나는 여러 가지 많은 포인트를 통해 작업 할 것이며 오히려 한 번에 하나씩 할 필요가 없으므로 중첩 루프에서 시도합니다.

도움을 주시면 감사하겠습니다. 도움이된다면 몇 가지 샘플 데이터에 대한 링크가 있습니다. http://dl.dropbox.com/u/17903768/AVHRR_output.txt 미리 감사드립니다! 벡터화

답변

1

사용 ifelse는 :

ifelse(data$point<= 6.25,-1.33,ifelse(data$point<= 8.25,-0.99,ifelse(data$point<= 11.25,-3.31,.... .Until 완료. 예를 들어

:

datap=read.table('http://dl.dropbox.com/u/17903768/AVHRR_output.txt',header=T) 


apply(datap[,5:9],2,function(x){ 
datap$x = 
ifelse(x<=6.25,1.33, 
ifelse(x<=8.75,-0.99, 
    ifelse(x<=11.25,-3.31, 
    ifelse(x<=13.75,-2.56, 
    ifelse(x<=16.25,-1.81, 
    ifelse(x<=18.75,-2.78, 
     ifelse(x<=21.25,-3.75, 
     ifelse(x<=23.75,-1.98,-0.21))))))))}) 
+0

도움을 주셔서 감사합니다. – user1209587

0

여기에 단지 전에 논리를 사용하여 다른 방법 다음 apply 부분은 모든 "온도"컬럼을 통해 당신을 얻을 수 있도록

DAT <- read.table("http://dl.dropbox.com/u/17903768/AVHRR_output.txt",header=TRUE,as.is=TRUE) 

    recodecolumn <- function(x){ 
     out <- vector(length=length(x)) 
     out[x < 6.25] <- 1.33 
     out[x >= 6.25 & x < 8.75] <- .99 
     out[x >= 8.75 & x < 11.25] <- 3.31 
     out[x >= 11.25 & x < 13.25] <- 2.56 
     out[x >= 13.25 & x < 16.25] <- 1.81 
     out[x >= 16.25 & x < 18.75] <- 2.78 
     out[x >= 18.75 & x < 21.25] <- 3.75 
     out[x >= 21.25 & x < 23.75] <- 1.98 
     out[x >= 23.75 & x < 26.25] <- 0.21 
      out 
    } 

    NewCols <- apply(DAT[,5:9],2,recodecolumn) 
    colnames(NewCols) <- paste("rate",1928:1932,sep="_") 
    DAT <- cbind(DAT,NewCols) 
+0

감사합니다. 매우 도움이되었습니다. 나는 배울 것이 너무 많다! – user1209587

1

안드레스의 대답은 아주 좋습니다. 나는 실험하기 (직장에서) R의 사본없이 여기 붙어있어,하지만 당신은 당신의 컷오프의 벡터가 xcut <- c(0,6.25,8.75,.11.25,...
값 그냥 어떻게 만들 수 있을지 의심 당신이 훨씬 간단 조금해야합니다 x <- xcut[(which(x>xcut))]

코드를 쉽게 편집 할 수 있습니다. 이미 벡터화로 findInterval이 같은 상황에서 유용 대신 다른 문 경우 중첩 된 것을 내가 발견

0

: (주 나는 작은 x 값 :-) 문제를 방지 할 수있는 0 값을 추가)하고 내 위치를 반환 컷오프 포인트의 벡터.

DAT <- read.table("http://dl.dropbox.com/u/17903768/AVHRR_output.txt",header=TRUE,as.is=TRUE) 

recode.fn <- function(x){ 
    cut.vec <- c(0, seq(6.25,26.25,by = 2.5),Inf) 
    recode.val <- c(-1.33, 0.99, 3.31, 2.56,1.81,2.78,3.75,1.98, 0.21) 
    cut.interval <- findInterval(x, cut.vec, FALSE) 
    return(recode.val[cut.interval]) 
} 

# Add on recoded data to existing data frame 
DAT[,10:14] <- sapply(DAT[,5:9],FUN=recode.fn) 
+0

! Ninja'd 나 1 분 :-). 내 대답은, 내가 올바르게했을 때,'findInterval'에 변형 된 것일뿐입니다. 좋은 대답, 짐. –

+0

전에 이걸 본 적이 없다. 멋지다. –