[英]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.