声明:编写一个接受日期作为输入的函数,并返回与该日期对应的黄道带的星座(使用Lubridate
包)。
问题:当我输入" 12月22日和#34;之间的任何日期时和" 1月19日"。它返回NULL
。
ymd
应该返回2017-12-22 UTC--2018-01-19 UTC
而不是2017-12-22 UTC--2017-01-19 UTC
。
有没有更好的方法来生成Date
/ POSIx
数据的时间间隔?
zodiac_sign <- function(input){
library(lubridate)
input <- ymd(as.character(as.Date(input,format="%B %d")))
x <- as.Date(c("March 21","April 19","April 20","May 20","May 21","June 20","June 21","July 22","July 23","August 22","August 23","September 22","September 23","October 22","October 23","November 21","November 22","December 21","December 22","January 19","January 20","February 18","February 19","March 20"),format="%B %d")
x_dateform_char <- as.character(x)
lst <- list()
for(i in seq(1,length(x_dateform_char),2)) {
lst[[i]] <- c(ymd(x_dateform_char[i]) %--% ymd(x_dateform_char[i+1]))
if(i==(length(x_dateform_char)-1)){
break
}
}
lst <- lst[!sapply(lst, is.null)]
names(lst) <-
c("Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittari
us","Capricorn","Aquarius","Pisces")
lst
for(i in 1:length(lst)){
if(input %within% lst[[i]]){
sign <- names(lst)[i]
} }
sign
}
答案 0 :(得分:2)
黄道带标志通常取决于月份的日期,而年份不起任何作用。因此,我想尝试完全忽略评估逻辑中的年份部分。
我考虑的逻辑基于日期(一个月的command-line-tools
),该日期在该月划分黄道十二宫。然后,只需从输入值中明确考虑day
和month
部分。
day
上述逻辑中使用的zodiac_sign <- function(input){
library(lubridate)
input <- ymd(as.character(as.Date(input,format="%B %d")))
# Define data.frame for zodiac_sign
zodiac_sign_df <- data.frame(Month = c("March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "January", "February"),
Zodiac_Separation_Dt = c(21, 20, 21, 21, 23, 23, 23, 23, 22, 22, 20, 19),
LowerSideZS = c("Pisces", "Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius"),
UpperSideZS = c("Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn","Aquarius", "Pisces"),
stringsAsFactors = FALSE )
# Filter data with matching month
val_df <- zodiac_sign_df[zodiac_sign_df$Month == months(input), ]
zodiac_sign <- ifelse( day(input) >= val_df$Zodiac_Separation_Dt, val_df$UpperSideZS, val_df$LowerSideZS)
zodiac_sign
}
如下所示:
zodiac_sign_df
答案 1 :(得分:1)
我已经重新编辑了您的代码以生成您需要的结果
zodiac_sign <- function(input){
nms<- input
library(lubridate)
input <-ymd(as.character(as.Date(input,format="%B %d")))
x <- as.Date(c("January 20","February 18",
"February 19","March 20","March 21","April 19","April 20","May 20","May 21","June 20",
"June 21","July 22","July 23","August 22","August 23","September 22",
"September 23","October 22","October 23","November 21","November 22",
"December 21","December 22","January 19"),format="%B %d")
zodiac_name<-c("Aquarius","Pisces","Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra",
"Scorpio","Sagittarius","Capricorn")
lst=lapply(split(x,rep(1:12,each=2)),function(y){if(y[2]<y[1])y[2]=y[2]+365;c(y[1]%--%y[2])})
limit=format(ymd(as.character(as.Date("Jan 20",format="%B %d"))),format="%m-%d")
lower=format(input,format="%m-%d")<limit
input[lower]=input[lower]+365
result=which(mapply(`%within%`,list(input),lst),T)
if(is.matrix(result))setNames(zodiac_name[result[order(result[,1]),2]],nms)
else setNames(zodiac_name[result],nms)
}
zodiac_sign(c("Jan 10","Mar 20", "Aug 30", "Sep 25","Dec 22","Dec 25"))
Jan 10 Mar 20 Aug 30 Sep 25 Dec 22 Dec 25
"Capricorn" "Pisces" "Virgo" "Libra" "Capricorn" "Capricorn"