簡體   English   中英

根據周數 (ISOweek) 將 ID 向量分配給 R 中的數據幀

[英]Assigning an ID vector to a dataframe in R, based on week number (ISOweek)

我正在嘗試將 ID 代碼添加到數據框(筒子架)中,這是從 2000 年到 2015 年的貝類登陸時間序列。前幾列如下:

    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,“ab”是 Yell,“ac”是 Foula 等等。 如果 Mousa 的所有者隨后購買了數據框中的新船,則“aa”將與他們一起使用並分配給新船名。

周向量是使用 ISOweek 函數根據實際日期創建的。 周向量是一個有序因子,因此 R 知道時間序列中從開始到結束的正確順序:

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

我曾嘗試為一艘船添加唯一的 fID 代碼,但它不起作用:

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

“aa”是我想在 fID 向量中分配的代碼,僅在 2004-W53 和 2015-W53 周之間。 我不確定 R 在與周一起使用時是否會識別 > 或 < - 我確實發現 unclass(creel$week) 給出了可以替代的周數的實際值。

我也嘗試使用 ifelse,但僅適用於船主在整個數據集中沒有改變的船(在這種情況下,一周無關緊要)。 像這樣的東西,(也不起作用!):

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

數據集非常大,但如果更容易的話,我很樂意單獨進行每個人/船的組合。

更新:這是我擁有的另一個 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”,而韋恩在比爾之后擁有“Yell”。 我需要 James 的 ID 在他擁有 Foula 和 Mousa 的那幾周內保持為“ac”(也就是說,我可以通過時間追蹤漁夫,而不必只是船)。

不過,這就是我要做的,可能有更好的方法。 我使用dplyr但只是略微計算每周的觀察值。 我相信其他一切都是在基礎 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

如果您想將它們全部重新組合到一個大data.frame

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

編輯:我花了一個多小時試圖弄清楚如何使用ISOweek值進行這項工作,但沒有運氣。 我絕對認為處理常規日期值會更容易。 這是我的解決方案,其中data.frame您提供的附加data.frame ,我稱之為mydata ,盡管它最終變成了mydata3 確實希望這對於大型數據集來說會相當慢,但我很確定它可以滿足您的需求:

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>

現在,如果您出於方便決定要使用ISOweek日期,那么:

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
....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM