我正在尝试将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,Yell的“ab”,上面的行中的Foula等的“ac”。如果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是否会识别&gt;或者&lt;当使用周数时 - 我确实发现unclass(creel $ week)给出了可以替代使用的周数的实际值。
我也尝试过使用ifelse,但仅适用于所有者在整个数据集中没有变化的船只(在这种情况下,周是不相关的)。像这样的东西,(也没用!):
creel$fID <- ifelse(creel$boat=="Unst", as.factor(creel$fID=="ad"), NA)
数据集非常大,但如果更容易的话,我很乐意单独做每个人/船组合。
更新: 这是我拥有的另一个例子,详细说明谁拥有哪艘船,以及何时:
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>
你可以看到詹姆斯拥有鲍勃之后的“穆萨”,并且韦恩在比尔之后拥有了“大喊”。我需要詹姆斯的身份证在他拥有Foula和Mousa的几个星期内保持“交流”(即我可以追踪渔夫的时间,不一定只是船)。
答案 0 :(得分:0)
这是我要做的,但是,可能有更好的方法。我使用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
我的解决方案,其中我称之为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
....