2016-06-18 5 views
0

データフレーム(クリール)にIDコードを追加しようとしています。これは2000年から2015年までの貝の着陸の時系列です。以下に列がいくつかあります:週番号(ISOweek)に基づいてRのデータフレームにIDベクトルを割り当てる

head(creel,10) 

      week year  boat fID 
    1 2000-W01 2000  Mousa NA 
    2 2000-W01 2000  Yell NA 
    3 2000-W01 2000  Foula NA 
    4 2000-W01 2000  Foula NA 
    5 2000-W02 2000  Foula NA 
    6 2000-W02 2000 Papa Stour NA 
    7 2000-W02 2000  Fetlar NA 
    8 2000-W02 2000  Unst NA 
    9 2000-W03 2000  Foula NA 
    10 2000-W03 2000 Fair Isle NA 
    ... 

IDはボートの所有者のものであり、時間とともに変化します。私は誰がどのボートを所有しているかについての詳細を持っており、 "fID"列に追加する固有のコードを作成しています(これを作成してNAで埋めました)。この目的のために、 "aa"はMousaのID、Yellの "ab"、上記の行のFoulaの "ac"などとしましょう。 Mousaの所有者がデータフレーム内にある新しいボートを購入すると、「aa」がそれらと共に移動し、新しいボート名に割り当てられます。

週ベクトルは、ISOweek関数を使用して実際の日付から作成されました。

creel$week <- as.ordered(creel$week) 
    #Levels:2000-W01 < 2000-W02 < 2000-W03 < 2000-W04 < 2000-W05<...<2015-W53 

私はそもそも1隻のボートのためのユニークなFIDコードを追加しようとしましたが、それはしませんでした:1週間ベクトルは、Rは、時系列的に最初から最後まで正しい順序を知っているので、注文した要因であります作品:

creel$fID[which(creel$boat=="Mousa" & creel$week=>"2004-W53" & creel$week=<"2015-W53"),] <- as.factor("aa") 

"AA" は、私が唯一の2004-W53および2015-W53週間の間、FIDベクトルに割り当てるしたいコードです。週に使用するときにRが>または<を認識するかどうかわかりませんでした - 私はunclass(creel $ week)が代わりに使用できる週番号の実際の値を与えることがわかりました。

また、ifelseを使用してみましたが、所有者がデータセット全体で変更されていないボートの場合のみ(その場合は週は関係ありません)。このような何かは、(!も動作しませんでした):私はそれが簡単だ場合は、個別に各人/ボートコンボを行うには満足しているものの

creel$fID <- ifelse(creel$boat=="Unst", as.factor(creel$fID=="ad"), NA) 

データセットは、非常に大きいです。

UPDATE:ここ はどのボート、そしてときに所有者その詳細は、私が持っているdfを他の例を示します

 Person code  boat1 date_from date_to boat2 date_from2 date_to2 
    1  Bob aa  Mousa 2002-W53 2005-W34 <NA>  <NA>  <NA> 
    2  Bill ab  Yell 1999-W52 2010-W52 <NA>  <NA>  <NA> 
    3 James ac  Foula 1999-W52 2005-W26 Mousa 2005-W35 2015-W53 
    4  Tom ad  Unst 1999-W52 2015-W53 <NA>  <NA>  <NA> 
    5 Willie ae Fetlar 2007-W35 2015-W53 <NA>  <NA>  <NA> 
    6 Wayne af  Yell 2011-W01 2013-W13 <NA>  <NA>  <NA> 

あなたはジェームズはボブの後に「Mousa」を所有し、そしてウェインということがわかりますBillの後に "Yell"を所有していた。私はFoulaとMousaの両方を所有していた週の間、 "ac"のままにするためにJamesのIDが必要です(つまり、私は漁師を時間通りに追跡することができます。

+0

idsの一般的な規則は指定していません。あなたは 'aa'の例だけを与えました。どのような行に「ac」を付けるべきか、どのように知っていますか? –

+0

@PierreLafortune acは、問題の人がボートを所有していた週番号のボート= Foulaのすべての行に移動します。ボートは、その後、人「ac」の後に他の人に売却され、新しい所有者IDが必要となる。全部で99人のオーナー(それぞれID付き)のボートオーナーシップの週番号があります。 –

+0

日付のフィルタリングでは、正確なソース日付を保持してみませんか?それらには "<" and ">" –

答えて

0

これは私がやることですが、可能性が高い方法があります。私はdplyrを使用していますが、1週間あたりの観測数にわずかにしかカウントできません。

creel.back_together<-rbind(creel.subset, creel[!creel$ref.week %in% c(1,2),]) 
creel.back_together 
     week year  boat fID ref.week 
1 2000-W01 2000  Mousa aa  1 
2 2000-W01 2000  Yell ab  1 
3 2000-W01 2000  Foula ac  1 
4 2000-W01 2000  Foula ac  1 
5 2000-W02 2000  Foula ac  2 
6 2000-W02 2000 Papa_Stour <NA>  2 
7 2000-W02 2000  Fetlar <NA>  2 
8 2000-W02 2000  Unst <NA>  2 
9 2000-W03 2000  Foula <NA>  3 
10 2000-W03 2000 Fair_Isle <NA>  3 

編集:私は、あなたが一つの大きなdata.frameに戻って一緒にそれをすべて入れたい場合は他のすべてがベースR.

library(dplyr) 

creel$ref.week<- rep(1:length(unique(creel$week)), 
        (creel %>% group_by(week) %>% summarise(n= n()))$n) 
#add a reference column 

creel.subset<-creel[creel$ref.week %in% c(1,2),] 
#subset the weeks you want by that reference column. Obviously your 
#reference weeks will be different. 

creel.subset$fID<-with(creel.subset, ifelse(boat =="Mousa", "aa", 
              ifelse(boat == "Yell", "ab", 
                ifelse(boat == "Foula", "ac", NA)))) 
#name the fID's however you want. This is just example. 

creel.subset 

     week year  boat fID ref.week 
1 2000-W01 2000  Mousa aa  1 
2 2000-W01 2000  Yell ab  1 
3 2000-W01 2000  Foula ac  1 
4 2000-W01 2000  Foula ac  1 
5 2000-W02 2000  Foula ac  2 
6 2000-W02 2000 Papa_Stour <NA>  2 
7 2000-W02 2000  Fetlar <NA>  2 
8 2000-W02 2000  Unst <NA>  2 

で行われていると信じて、私はどのように把握しようと時間以上を費やしこの値をISOweekの値で設定しますが、運は必要ありません。私は間違いなく、これは通常の日付の値を扱うのが簡単だと思います。ここに私がmydataと呼んだ追加のdata.frameの解決策がありますが、最終的にはmydata3になりました。私はが、これは大規模なデータセットのためにかなり遅くなることを期待しますが、私はそれはあなたが欠けている何をかなり確信している:あなたは利便性のうち、ISOweek日付で仕事をしたい決定した場合、

library(ISOweek) 
library(lubridate) 
library(data.table) 

fullWeek<-function(x){ 
    paste(x, "-1", sep = "") 
} 

creel$week<-as.character(creel$week) 
creel$week<-fullWeek(creel$week) 
creel$week<-ISOweek2date(creel$week) 
creel$week<-as_date(ymd(creel$week)) 

mydata1<-mydata[,1:5] 
mydata2<-mydata[,c(1:2,6:8)] 
colnames(mydata2)<-colnames(mydata1) 
mydata3<-na.omit(rbind(mydata1, mydata2)) 
mydata3[,4:5]<-sapply(mydata3[,4:5], fullWeek) 
mydata3[,4:5]<-lapply(mydata3[,4:5], ISOweek2date) 
mydata3[,4:5]<-lapply(mydata3[,4:5], function(x) as_date(ymd(x))) 
## undoing all of the ISOweek nonsense 

for(i in 1:nrow(mydata3)){ 
    boat1<-mydata3[i,]$boat1 
    date_from<-mydata3[i,]$date_from 
    date_to<-mydata3[i,]$date_to 
    code<-mydata3[i,]$code 

    for(j in 1:nrow(creel)){ 
    boat2<-creel[j,]$boat 
    date<-creel[j,]$week 

    if(boat1 == boat2 && date %between% c(date_from, date_to)) { 
    creel[j,]$fID<-code 
    } 
    } 
} 

creel 

     week year  boat fID 
2000-01-03 2000  Mousa <NA> 
2000-01-03 2000  Yell ab 
2000-01-03 2000  Foula ac 
2000-01-03 2000  Foula ac 
2000-01-10 2000  Foula ac 
2000-01-10 2000 Papa_Stour <NA> 
2000-01-10 2000  Fetlar <NA> 
2000-01-10 2000  Unst ad 
2000-01-17 2000  Foula ac 
2000-01-17 2000 Fair_Isle <NA> 

を今すぐ次に:

creel$week<-ISOweek(creel$week) 
creel 

    week year  boat fID 
2000-W01 2000  Mousa <NA> 
2000-W01 2000  Yell ab 
2000-W01 2000  Foula ac 
2000-W01 2000  Foula ac 
2000-W02 2000  Foula ac 
.... 
+0

私が正しく理解していれば、あなたの解決策はうまくいくでしょう。残念ながら、新しいボートが購入され、古いボートが販売されています(多くの場合、船隊内では同じボート名が新しい人物/ IDになります)。私は別のdfを作成しました - それぞれの人/ボートのコンボのための "from-to"の日付(週番号)。ありがとう –

+0

ボートが手を入れたたびに名前を更新する必要があります。購入/売却の日程があった場合は、その週にサブセット化してidを再適用することができます。新しい 'df 'を(それの一部)上に置くと、それをプログラム的に行う方法を思いつくのは簡単でしょう。 –

+0

ボートの日付の例を追加しました。うまくいけば、それは私が探しているものを少し明確にします。ありがとう。 –

関連する問題