2017-07-05 7 views
3

"私は3つの連続した" 1 "または"真 "の各観測の最初と最後の月を取得することです" 。最初の月と最後の月を2つの新しい列 "begin"と "end"を作成したいと思います。 私の最初の観測の例では、avrilと等しく始まり、juinと等しくなります。 5観測ではfevrierと等しくなり、avrilと等しくなります。 9観測では、janvierと等しくなり、火星と同じになります。 。 条件と行と列ダブルループ

...

は、私はこれを実行しようとしました:

nom <- letters[1:5] 
pseudo <- paste(name, 21:25, sep = "") 
janvier <- c(0, 1, 1, 1, 0) 
fevrier <- c(1, 1, 1, 1, 1) 
mars <- c(0, 0, 0, 1, 1) 
avril <- c(1, 1, 1, 0, 1) 
mai <- c(1, 0, 1, 1, 1) 
juin <- c(1, 1, 0, 1, 0) 

df <- data.frame(nom =nom, pseudo = pseudo, janvier = janvier, 
       fevrier = fevrier, mars = mars, avril = avril, 
       mai = mai, juin = juin) 

dfm <- as.matrix(df[, -c(1, 2)]) 

my_matrix <- matrix(nrow = 10, ncol = 6) 


for(i in 1:dim(dfm)[1]){ 
    for(j in 1:dim(dfm)[2]){ 
    if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){ 
     my_matrix[i, j] <- "periode_ok" 
     my_matrix[i, j+1] <- "periode_ok" 
     my_matrix[i, j+2] <- "periode_ok" 
    } 
    } 
} 

ouputをこのようになります。任意の助けがをapreciatedされます

begin <- c("avril", "no info", "no info", 
      "janvier", "fevrier", "avril", "no info", 
      "no info", "janvier", "fevrier") 
end <- c("juin", "no info", "no info", "mars", 
     "avril", "juin", "no info", "no info", 
     "mars", "avril") 

output <- data.frame(nom =nom, pseudo = pseudo, janvier = janvier, 
       fevrier = fevrier, mars = mars, avril = avril, 
       mai = mai, juin = juin, begin = begin,end = end) 
+1

'のために(1 J:()(DFMを暗く[2] -2))'これを使用します。 – Masoud

+1

'pseudo'は他のすべての変数と同じように5の長さでなければなりません。 – Masoud

+0

https://stackoverflow.com/questions/25316565/return-column-index-of-first-set-of-consecutive-values-in-data-frame-row-in-r – Masoud

答えて

5

1:dim(dfm)[1]のような構造体は、dim(dfm)[1]が0の場合、完全に有効なベクトル1:0が得られ、ループはベクトルまたはこの場合は行列の要素0を処理しようとするため、危険です。これは不正で、エラーが発生します。推奨される解決策は、seq_len(...)を使用することです。 第2に、dim(dfm)[.]の代わりにnrowncolを使用しました。 エラーが発生しました。 j + 1j + 2という列をアドレス指定しようとしているので、jncol(dfm)に達したときに債務が切れています。以下のコードは、ループ制限の最後の2つの要素を削除します。

n <- ncol(dfm) 
for(i in seq_len(nrow(dfm))){ 
    for(j in seq_len(n)[-c(n - 1, n)]){ 
    if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){ 
     my_matrix[i, j] <- "periode_ok" 
     my_matrix[i, j+1] <- "periode_ok" 
     my_matrix[i, j+2] <- "periode_ok" 
    } 
    } 
} 

my_matrix 
3

はもちろん、このためのベクトル化されたソリューションがありますが、あなたが修正したい場合は、先に2列のためにチェックしているとして、あなたのループのためにあなたはdfmマイナス2の次元にjを制限する必要があります。あなたがこれを提供したことに基づいて、あなたを助けるでしょう。しかし、5行のdfから10行(2回繰り返す)を得る方法は明確ではありません。

 my_matrix <- matrix("no info", nrow = 5, ncol = 2) 
     colnames(my_matrix) <- c("begin", "end") 


     for(i in 1:dim(dfm)[1]){ 
     for(j in 1:(dim(dfm)[2]-2)){ 
      if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){ 
      my_matrix[i, 1] <- colnames(dfm)[j] 
      my_matrix[i, 2] <- colnames(dfm)[j+2] 
      break 
      } 
     } 
     } 


output <- cbind(df, my_matrix) 

結果は次のようになります。

output 

# nom pseudo janvier fevrier mars avril mai juin begin  end 
# 1 a name21  0  1 0  1 1 1 avril juin 
# 2 b name22  1  1 0  1 0 1 no info no info 
# 3 c name23  1  1 0  1 1 0 no info no info 
# 4 d name24  1  1 1  0 1 1 janvier mars 
# 5 e name25  0  1 1  1 1 0 fevrier avril