我的真正目标是在表1中使用一个月的数值(即1月= 01,... 12月= 12;年份作为单独的列存在)并在表2中找到值,其中值为从一个月前返回。我不知道如何处理的问题是表1中的月份是1月(即2014-01),我如何从表格2返回与2013年12月(即2013-12)相关的价值?
我认为有一个程序包有一个过程来减少上面描述的年初条件的日期/月份会计。我没有将月份和年份列转换为实际日期以完成此任务的问题。
year1 <- c(2013, 2013, 2014)
year2 <- c(2013, 2013, 2014)
month1 <- c(04, 08, 01)
month2 <- c(03, 12, 08)
value1 <- c(4,6,10)
value2 <- c(6,3,8)
df1 <- data.frame(year1, month1, value1)
df2 <- data.frame(year2, month2, value2)
鉴于2014-01与df1的日期组合,df2的预期输出将是2013-12日期组合的值2 = 3.
提前致谢
答案 0 :(得分:1)
我发现使用Date
对象更方便,因为添加/减去天或月更容易(感谢lubridate
包)。因此,我们的想法是将一个月的第一天用作日期字段,而不是使用年份和月份的单独字段。
此外,我更喜欢data.table
进行数据操作。
# initial data
df1 <- data.frame(year1=c(2013, 2013, 2014), month1=c(04, 08, 01), value1=c(4,6,10))
df2 <- data.frame(year2=c(2013, 2013, 2014), month2=c(03, 12, 08), value2=c(6,3,8))
library(data.table) # CRAN version 1.10.4 used
library(lubridate) # CRAN version 1.6.0 used
# coerce 1st data.frame to data.table,
# create date from year and month, skip year and month columns,
# create join date which is one month earlier
DT1 <- setDT(df1)[, .(date1 = as.Date(sprintf("%4i-%02i-01", year1, month1)),
value1)][, join.date := date1 - months(1L),]
# coerce 2nd data.frame to data.table,
# create date from year and month, skip year and month columns,
DT2 <- setDT(df2)[, .(date2 = as.Date(sprintf("%4i-%02i-01", year2, month2)),
value2)]
# right join: take all rows of DT1
DT2[DT1, on = c(date2 = "join.date")]
# date2 value2 date1 value1
#1: 2013-03-01 6 2013-04-01 4
#2: 2013-07-01 NA 2013-08-01 6
#3: 2013-12-01 3 2014-01-01 10
答案 1 :(得分:0)
这是一个解决方法,但这里有一个可能有用的想法:而不是仅减去1,减去2,使用模运算符然后再加1。
sudo
答案 2 :(得分:0)
您可以合并数据框(经过一些操作):
df1 <- data.frame(year1=c(2013, 2013, 2014), month1=c(04, 08, 01), value1=c(4,6,10))
df2 <- data.frame(year2=c(2013, 2013, 2014), month2=c(03, 12, 08), value2=c(6,3,8))
df1$month2 <- ifelse(df1$month1==1, 12, df1$month - 1)
df1$year2 <- ifelse(df1$month2==12, df1$year1-1, df1$year1)
merge(df1, df2, all.x=TRUE)
# month2 year2 year1 month1 value1 value2
# 1 3 2013 2013 4 4 6
# 2 7 2013 2013 8 6 NA
# 3 12 2013 2014 1 10 3