最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - calendR - "Error in if (special.days != "weekend" { : the condition has length > 1&quo

programmeradmin0浏览0评论

I am having issues plotting data using calendR package in R. I am using calendR to create a calendar plot of the air quality index (AQI) category for each day a community had data onto a 2024 calendar. I'm able to successfully plot one community, but not the other. For the community I cannot plot I keep getting the error "Error in if (special.days != "weekend") { : the condition has length > 1". I'm unable to find any information on the web relating to this error code or issue.

See below code for reproducible data and how I coded to generate the calendR plots.

library(calendR)
library(tidyverse)

#create data for community 1
julian_community1 <- c(299:366) #julian days for October 25 - December 31
#create list of PM2.5 readings in community 1 from October 25 - December 31
PM25_community1 <- c(3.4,1.3,1.2,1.2,0.4,3.4,1.0, #october data
                     0.8,0.3,6.0,0.9,5.3,4.4,3.4,1.2,0.7,0.6,0.8,0.3,0.9,0.9,4.1,0.7,0.3,0.4,2.1,1.4,5.2,4.2,3.9,1.4,0.8,0.7,0.8,0.3,1.9,0.8, #november data
                     0.7,1.2,1.7,1.8,3.8,6.1,5.9,1.2,0.7,0.3,0.6,2.9,2.5,1.1,0.5,0.9,1.5,1.1,0.8,1.5,0.8,2.2,4.6,1.2,1.0,3.3,0.9,0.9,4.6,1.2,2.8#december data
)
site_community1 <- rep("community 1", 68) #repeat community 1 site name 68 times (68 days between October 25 - December 31)

#create data for community 2
julian_community2 <- c(69:366) #julian days for March 9 - December 31
#create list of PM2.5 readings in community 2 from March 9 - December 31
PM25_community2 <- c(1.6,1.5,3.4,5.8,5.1,2.6,5.4,2.8,2.5,3.7,6.2,4.8,rep(NA,286)) 
site_community2 <- rep("community 2", 298) #repeat community 2 site name 298 times (298 days between March 9 - December 31)

#create data frame with both communities
data <- as.data.frame(c(julian_community1,julian_community2))
colnames(data) <- "julian"
data$PM25 <- c(PM25_community1, PM25_community2)
data$site_name <- c(site_community1,site_community2)

#create AQI category for each PM25 value
one <- data$PM25 <= 9.0
two <- data$PM25 >= 9.1 & data$PM25 <= 35.4
three <- data$PM25 >= 35.5 & data$PM25 <= 55.4
four <- data$PM25 >= 55.5 & data$PM25 <= 125.4
five <- data$PM25 >= 125.5 & data$PM25 <= 225.4
six <- data$PM25 >= 225.5
data$AQI <- NA
data <- data %>% mutate(AQI = case_when(
  one ~ "1",
  two ~ "2",
  three ~ "3",
  four ~ "4",
  five ~ "5",
  six ~ "6"
))

Then I plotted community 1 successfully

community <- "community 1"
year <- 2024


#create objects with days in each AQI category
good <- data %>% filter(site_name == community & AQI == 1)
moderate <- data %>% filter(site_name == community & AQI == 2)
unhealthy_sg <- data %>% filter(site_name == community & AQI == 3)
unhealthy <- data %>% filter(site_name == community & AQI == 4)
veryunhealthy <- data %>% filter(site_name == community & AQI == 5)
hazardous <- data %>% filter(site_name == community & AQI == 6)

#create event list with days in each category
events <- rep(NA, 365)
events[good$julian] <- "Good" 
events[moderate$julian] <- "Moderate"
events[unhealthy_sg$julian] <- "Unhealthy for sensitive groups"
events[unhealthy$julian] <- "Unhealhty"
events[veryunhealthy$julian] <- "Very unhealthy"
events[hazardous$julian] <- "Hazardous"
levels(factor(events))

#create color list
communitydata <- data %>% filter(site_name == community) #filter down to just data from given community
uniqueAQI <- unique(communitydata$AQI) #what AQI categories exist in the data from given community
#create a list of colors mutated by case when, for unique AQI groups for each community to feed into calendR
color <- data.frame(uniqueAQI)
color$color <- NA
green <- color$uniqueAQI == 1
yellow <- color$uniqueAQI == 2
orange <- color$uniqueAQI == 3
red <- color$uniqueAQI == 4
purple <- color$uniqueAQI == 5
maroon <- color$uniqueAQI == 6
color <- color %>% mutate(color = case_when(
  green ~ "green",
  yellow ~ "yellow",
  orange ~ "orange",
  red ~ "red",
  purple ~ "purple",
  maroon ~ "maroon"
))
palette <- as.vector(subset(color$color, !(is.na(color$color)))) #create palette vector to feed into calendR
desired_order <- c("green","yellow","orange","red","purple","maroon")
palette <- palette[order(match(palette, desired_order))]

#create plot
calendR(year = year,
        start = "M",
        special.days = events,
        special.col = palette, #adjust colors to the unique(data$AQI)
        low.col = "white",
        legend.pos = "right",
        legend.title = "Air Quality Index",
        title = paste(community,"AQI in 2024" ),
        mbg.col = "lightgray", #background color behind month title
        months.col = "white", #color of month text
        weeknames = c("M","T","W","T","F","S","S")
)

But when I try to plot community 2 I get the error "Error in if (special.days != "weekend") { : the condition has length > 1"

community <- "community 2"
year <- 2024


#create objects with days in each AQI category
good <- data %>% filter(site_name == community & AQI == 1)
moderate <- data %>% filter(site_name == community & AQI == 2)
unhealthy_sg <- data %>% filter(site_name == community & AQI == 3)
unhealthy <- data %>% filter(site_name == community & AQI == 4)
veryunhealthy <- data %>% filter(site_name == community & AQI == 5)
hazardous <- data %>% filter(site_name == community & AQI == 6)

#create event list with days in each category
events <- rep(NA, 365)
events[good$julian] <- "Good" 
events[moderate$julian] <- "Moderate"
events[unhealthy_sg$julian] <- "Unhealthy for sensitive groups"
events[unhealthy$julian] <- "Unhealhty"
events[veryunhealthy$julian] <- "Very unhealthy"
events[hazardous$julian] <- "Hazardous"
levels(factor(events))

#create color list
communitydata <- data %>% filter(site_name == community) #filter down to just data from given community
uniqueAQI <- unique(communitydata$AQI) #what AQI categories exist in the data from given community
#create a list of colors mutated by case when, for unique AQI groups for each community to feed into calendR
color <- data.frame(uniqueAQI)
color$color <- NA
green <- color$uniqueAQI == 1
yellow <- color$uniqueAQI == 2
orange <- color$uniqueAQI == 3
red <- color$uniqueAQI == 4
purple <- color$uniqueAQI == 5
maroon <- color$uniqueAQI == 6
color <- color %>% mutate(color = case_when(
  green ~ "green",
  yellow ~ "yellow",
  orange ~ "orange",
  red ~ "red",
  purple ~ "purple",
  maroon ~ "maroon"
))
palette <- as.vector(subset(color$color, !(is.na(color$color)))) #create palette vector to feed into calendR
desired_order <- c("green","yellow","orange","red","purple","maroon")
palette <- palette[order(match(palette, desired_order))]

#create plot
calendR(year = year,
        start = "M",
        special.days = events,
        special.col = palette, #adjust colors to the unique(data$AQI)
        low.col = "white",
        legend.pos = "right",
        legend.title = "Air Quality Index",
        title = paste(community,"AQI in 2024" ),
        mbg.col = "lightgray", #background color behind month title
        months.col = "white", #color of month text
        weeknames = c("M","T","W","T","F","S","S")
)

I am having issues plotting data using calendR package in R. I am using calendR to create a calendar plot of the air quality index (AQI) category for each day a community had data onto a 2024 calendar. I'm able to successfully plot one community, but not the other. For the community I cannot plot I keep getting the error "Error in if (special.days != "weekend") { : the condition has length > 1". I'm unable to find any information on the web relating to this error code or issue.

See below code for reproducible data and how I coded to generate the calendR plots.

library(calendR)
library(tidyverse)

#create data for community 1
julian_community1 <- c(299:366) #julian days for October 25 - December 31
#create list of PM2.5 readings in community 1 from October 25 - December 31
PM25_community1 <- c(3.4,1.3,1.2,1.2,0.4,3.4,1.0, #october data
                     0.8,0.3,6.0,0.9,5.3,4.4,3.4,1.2,0.7,0.6,0.8,0.3,0.9,0.9,4.1,0.7,0.3,0.4,2.1,1.4,5.2,4.2,3.9,1.4,0.8,0.7,0.8,0.3,1.9,0.8, #november data
                     0.7,1.2,1.7,1.8,3.8,6.1,5.9,1.2,0.7,0.3,0.6,2.9,2.5,1.1,0.5,0.9,1.5,1.1,0.8,1.5,0.8,2.2,4.6,1.2,1.0,3.3,0.9,0.9,4.6,1.2,2.8#december data
)
site_community1 <- rep("community 1", 68) #repeat community 1 site name 68 times (68 days between October 25 - December 31)

#create data for community 2
julian_community2 <- c(69:366) #julian days for March 9 - December 31
#create list of PM2.5 readings in community 2 from March 9 - December 31
PM25_community2 <- c(1.6,1.5,3.4,5.8,5.1,2.6,5.4,2.8,2.5,3.7,6.2,4.8,rep(NA,286)) 
site_community2 <- rep("community 2", 298) #repeat community 2 site name 298 times (298 days between March 9 - December 31)

#create data frame with both communities
data <- as.data.frame(c(julian_community1,julian_community2))
colnames(data) <- "julian"
data$PM25 <- c(PM25_community1, PM25_community2)
data$site_name <- c(site_community1,site_community2)

#create AQI category for each PM25 value
one <- data$PM25 <= 9.0
two <- data$PM25 >= 9.1 & data$PM25 <= 35.4
three <- data$PM25 >= 35.5 & data$PM25 <= 55.4
four <- data$PM25 >= 55.5 & data$PM25 <= 125.4
five <- data$PM25 >= 125.5 & data$PM25 <= 225.4
six <- data$PM25 >= 225.5
data$AQI <- NA
data <- data %>% mutate(AQI = case_when(
  one ~ "1",
  two ~ "2",
  three ~ "3",
  four ~ "4",
  five ~ "5",
  six ~ "6"
))

Then I plotted community 1 successfully

community <- "community 1"
year <- 2024


#create objects with days in each AQI category
good <- data %>% filter(site_name == community & AQI == 1)
moderate <- data %>% filter(site_name == community & AQI == 2)
unhealthy_sg <- data %>% filter(site_name == community & AQI == 3)
unhealthy <- data %>% filter(site_name == community & AQI == 4)
veryunhealthy <- data %>% filter(site_name == community & AQI == 5)
hazardous <- data %>% filter(site_name == community & AQI == 6)

#create event list with days in each category
events <- rep(NA, 365)
events[good$julian] <- "Good" 
events[moderate$julian] <- "Moderate"
events[unhealthy_sg$julian] <- "Unhealthy for sensitive groups"
events[unhealthy$julian] <- "Unhealhty"
events[veryunhealthy$julian] <- "Very unhealthy"
events[hazardous$julian] <- "Hazardous"
levels(factor(events))

#create color list
communitydata <- data %>% filter(site_name == community) #filter down to just data from given community
uniqueAQI <- unique(communitydata$AQI) #what AQI categories exist in the data from given community
#create a list of colors mutated by case when, for unique AQI groups for each community to feed into calendR
color <- data.frame(uniqueAQI)
color$color <- NA
green <- color$uniqueAQI == 1
yellow <- color$uniqueAQI == 2
orange <- color$uniqueAQI == 3
red <- color$uniqueAQI == 4
purple <- color$uniqueAQI == 5
maroon <- color$uniqueAQI == 6
color <- color %>% mutate(color = case_when(
  green ~ "green",
  yellow ~ "yellow",
  orange ~ "orange",
  red ~ "red",
  purple ~ "purple",
  maroon ~ "maroon"
))
palette <- as.vector(subset(color$color, !(is.na(color$color)))) #create palette vector to feed into calendR
desired_order <- c("green","yellow","orange","red","purple","maroon")
palette <- palette[order(match(palette, desired_order))]

#create plot
calendR(year = year,
        start = "M",
        special.days = events,
        special.col = palette, #adjust colors to the unique(data$AQI)
        low.col = "white",
        legend.pos = "right",
        legend.title = "Air Quality Index",
        title = paste(community,"AQI in 2024" ),
        mbg.col = "lightgray", #background color behind month title
        months.col = "white", #color of month text
        weeknames = c("M","T","W","T","F","S","S")
)

But when I try to plot community 2 I get the error "Error in if (special.days != "weekend") { : the condition has length > 1"

community <- "community 2"
year <- 2024


#create objects with days in each AQI category
good <- data %>% filter(site_name == community & AQI == 1)
moderate <- data %>% filter(site_name == community & AQI == 2)
unhealthy_sg <- data %>% filter(site_name == community & AQI == 3)
unhealthy <- data %>% filter(site_name == community & AQI == 4)
veryunhealthy <- data %>% filter(site_name == community & AQI == 5)
hazardous <- data %>% filter(site_name == community & AQI == 6)

#create event list with days in each category
events <- rep(NA, 365)
events[good$julian] <- "Good" 
events[moderate$julian] <- "Moderate"
events[unhealthy_sg$julian] <- "Unhealthy for sensitive groups"
events[unhealthy$julian] <- "Unhealhty"
events[veryunhealthy$julian] <- "Very unhealthy"
events[hazardous$julian] <- "Hazardous"
levels(factor(events))

#create color list
communitydata <- data %>% filter(site_name == community) #filter down to just data from given community
uniqueAQI <- unique(communitydata$AQI) #what AQI categories exist in the data from given community
#create a list of colors mutated by case when, for unique AQI groups for each community to feed into calendR
color <- data.frame(uniqueAQI)
color$color <- NA
green <- color$uniqueAQI == 1
yellow <- color$uniqueAQI == 2
orange <- color$uniqueAQI == 3
red <- color$uniqueAQI == 4
purple <- color$uniqueAQI == 5
maroon <- color$uniqueAQI == 6
color <- color %>% mutate(color = case_when(
  green ~ "green",
  yellow ~ "yellow",
  orange ~ "orange",
  red ~ "red",
  purple ~ "purple",
  maroon ~ "maroon"
))
palette <- as.vector(subset(color$color, !(is.na(color$color)))) #create palette vector to feed into calendR
desired_order <- c("green","yellow","orange","red","purple","maroon")
palette <- palette[order(match(palette, desired_order))]

#create plot
calendR(year = year,
        start = "M",
        special.days = events,
        special.col = palette, #adjust colors to the unique(data$AQI)
        low.col = "white",
        legend.pos = "right",
        legend.title = "Air Quality Index",
        title = paste(community,"AQI in 2024" ),
        mbg.col = "lightgray", #background color behind month title
        months.col = "white", #color of month text
        weeknames = c("M","T","W","T","F","S","S")
)
Share Improve this question asked Feb 6 at 18:31 Kelly IrelandKelly Ireland 1278 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Fix

2024 had 366 days, since it's a leap year. So change events <- rep(NA, 365) to events <- rep(NA, 366).

Add

I would change your code a little, to make it more robust. Notably, I make the dataframe definitions a little more concise and use as.numeric(format(as.Date(paste(year, "12", "31", sep="-")), "%j")) to figure out, how many days the year had.

library(calendR); library(tidyverse)    

# Community 1 data (Oct 25 - Dec 31)
community1_data <- data.frame(
  julian = 299:366,
  PM25 = c(3.4,1.3,1.2,1.2,0.4,3.4,1.0, #october data
           0.8,0.3,6.0,0.9,5.3,4.4,3.4,1.2,0.7,0.6,0.8,0.3,0.9,0.9,4.1,0.7,0.3,0.4,2.1,1.4,5.2,4.2,3.9,1.4,0.8,0.7,0.8,0.3,1.9,0.8, #november data
           0.7,1.2,1.7,1.8,3.8,6.1,5.9,1.2,0.7,0.3,0.6,2.9,2.5,1.1,0.5,0.9,1.5,1.1,0.8,1.5,0.8,2.2,4.6,1.2,1.0,3.3,0.9,0.9,4.6,1.2,2.8 #december data
  ),
  site_name = "community 1"
)

# Community 2 data (Mar 9 - Dec 31)
community2_data <- data.frame(
  julian = 69:366,
  PM25 = c(1.6,1.5,3.4,5.8,5.1,2.6,5.4,2.8,2.5,3.7,6.2,4.8,rep(NA,length(69:366)-12)),
  site_name = "community 2"
)

# Combine both communities
data <- rbind(community1_data, community2_data)

#create AQI category for each PM25 value
data$AQI <- case_when(
  data$PM25 <= 9.0 ~ "1",
  data$PM25 >= 9.1 & data$PM25 <= 35.4 ~ "2",
  data$PM25 >= 35.5 & data$PM25 <= 55.4 ~ "3",
  data$PM25 >= 55.5 & data$PM25 <= 125.4 ~ "4",
  data$PM25 >= 125.5 & data$PM25 <= 225.4 ~ "5",
  data$PM25 >= 225.5 ~ "6",
  TRUE ~ NA_character_
)

plot_calendar <- function(df, community, year){ # make use of a function

  #create objects with days in each AQI category
  filtered_data <- data %>% filter(site_name == community)
  
  #create event list for all days of the year
  days_in_year <- as.numeric(format(as.Date(paste(year, "12", "31", sep="-")), "%j"))
  events <- rep(NA, days_in_year)
  events[filtered_data$julian] <- case_when(
    filtered_data$AQI == "1" ~ "Good",
    filtered_data$AQI == "2" ~ "Moderate",
    filtered_data$AQI == "3" ~ "Unhealthy for sensitive groups",
    filtered_data$AQI == "4" ~ "Unhealthy",
    filtered_data$AQI == "5" ~ "Very unhealthy",
    filtered_data$AQI == "6" ~ "Hazardous",
    TRUE ~ NA_character_
  )
  
  #create color palette
  all_categories <- c("1", "2", "3", "4", "5", "6")
  colors <- c("green", "yellow", "orange", "red", "purple", "maroon")
  palette <- colors[match(unique(filtered_data$AQI[!is.na(filtered_data$AQI)]), all_categories)]
  
  #create plot
  calendR(year = year,
          start = "M",
          special.days = events,
          special.col = palette,
          low.col = "white",
          legend.pos = "right",
          legend.title = "Air Quality Index",
          title = paste(community, "AQI in", year),
          mbg.col = "lightgray",
          months.col = "white",
          weeknames = c("M","T","W","T","F","S","S")) # this returns the calendar plot 
 
}
# calling functions with filters shows the plot
plot_calendar(data, "community 1", 2024)
plot_calendar(data, "community 2", 2024)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论