我有一个如下所示的数据框:
species<-"ABC" ind<-rep(1:4,each=24) hour<-rep(seq(0,23,by=1),4) month<-rep(seq(1,12),8) depth<-runif(length(ind),1,50) df<-data.frame(species,ind,month,hour,depth)
我想要的是使用列月来指定每个季节的间隔,并在同一数据框的新列中返回这些值。我在季节中使用这个代码,似乎工作正常,
# Classify months into seasons summer<-c(1,2,12) fall<-c(3,4,5) winter<-c(6,7,8) spring<-c(9,10,11) # Create a new column with seasons df$season<-NA for(i in 1:nrow(df)){ if(df$month[i]%in%summer){df$season[i]<-"1-summer"} else if(df$month[i]%in%fall){df$season[i]<-"2-fall"} else if(df$month[i]%in%winter){df$season[i]<-"3-winter"} else if(df$month[i]%in%spring){df$season[i]<-"spring"}
}
然而,这个循环已经在更大的循环内部,具有更复杂和更大的数据库。所以我一直在寻找一种更快,更有效的方法。我使用循环而不是剪切或子集我的原始数据框的原因是因为我使用的第一个循环是分离并对各个动物进行分析。由此产生的数据框架的长度因动物而异,我遇到的一个问题是并非所有动物都在所有月份都存在,所以当我试图在循环中为在特定季节不存在的动物分配季节时,然后R给了我一个错误信息......
答案 0 :(得分:2)
seasons <- c("1-summer", "2-fall", "3-winter", "spring")
df$season2 <- factor(trunc(df$month %% 12 / 3) + 1, labels = seasons)
table(df$season, df$season2)
如果您愿意,可以将df$season2
转换为character
。
答案 1 :(得分:1)
我只是为季节名称生成查找表并应用它:
> season.names <- rep("",12)
> season.names[summer] <- "1-summer"
> season.names[fall] <- "2-fall"
> season.names[winter] <- "3-winter"
> season.names[spring] <- "4-spring"
> season.names
[1] "1-summer" "1-summer" "2-fall" "2-fall" "2-fall" "3-winter" "3-winter"
[8] "3-winter" "4-spring" "4-spring" "4-spring" "1-summer"
> df$season <- season.names[df$month]
> head(df)
species ind month hour depth season
1 ABC 1 1 0 41.643471 1-summer
2 ABC 1 2 1 36.055533 1-summer
3 ABC 1 3 2 1.901639 2-fall
4 ABC 1 4 3 7.737539 2-fall
5 ABC 1 5 4 35.327364 2-fall
6 ABC 1 6 5 9.156978 3-winter