将每日data.frame与年度data.frame合并

时间:2014-04-18 11:35:53

标签: r merge dataframe

我想合并两个数据帧。一个包含每日数据和另一个年度数据。 我怎么能这样做?

date <- c("05.06.2001","02.10.2003","06.12.2004","01.01.2001","01.04.2003")
company <- c(1,1,1,2,2)

mydf <- data.frame(date, company)
mydf

#         date company
# 1 05.06.2001       1
# 2 02.10.2003       1
# 3 06.12.2004       1
# 4 01.01.2001       2
# 5 01.04.2003       2

# annual data

YEAR <- c(2001, 2002, 2003, 2004, 2005, 2001, 2002, 2003, 2004, 2005)
COMPANY <- c(1,1,1,1,1,2,2,2,2,2)
VARIABLE <- c(120, 230, 99, 38, 21, 20, 24, 420, 203, 180)

annual <- data.frame(YEAR, COMPANY, VARIABLE)
annual

#    YEAR COMPANY VARIABLE
# 1  2001       1      120
# 2  2002       1      230
# 3  2003       1       99
# 4  2004       1       38
# 5  2005       1       21
# 6  2001       2       20
# 7  2002       2       24
# 8  2003       2      420
# 9  2004       2      203
# 10 2005       2      180

# the output should be:

#         date company VARIABLE
# 1 05.06.2001       1      120
# 2 02.10.2003       1       99
# 3 06.12.2004       1       38
# 4 01.01.2001       2       20
# 5 01.04.2003       2      420

谢谢!

2 个答案:

答案 0 :(得分:1)

您有几个选择:

选项1:使用包lubridate

require(luubridate)   ## install it first if you don't have it
mydf$year <- year(mydf$date)
merged.df <- merge(mydf, annual, by.x=c('company', 'year'), by.y=c('COMPANY', 'YEAR'))

选项2:使用data.table

data.table更多的是投资(强烈推荐),并且它具有处理日期的内置函数。它还具有许多其他出色的功能(快速合并,分组,降低内存使用),并使合并过程更加高效。

答案 1 :(得分:1)

以下是一些解决方案。在这些(除了sqldf解决方案)之外,我们将使用以下函数:

d2y <- function(date) as.numeric(substring(date, 7))
lower.names <- function(DF) setNames(DF, tolower(names(DF)))

基础R 这是基础解决方案。虽然不是示例中的情况,但为了安全起见,我们会执行加入,以防mydfannual中的任何日期在mydf2 <- transform(mydf, year = d2y(date)) merge(mydf2, lower.names(annual), all.x = TRUE) 中没有相应的年份。左连接将确保不删除此类日期:

mydf2

sqldf 这是一个sqldf解决方案。这有点整洁,因为我们不必具体化d2y,而是可以直接加入复杂的逻辑表达式。请注意,此解决方案不使用lower.nameslibrary(sqldf) sqldf("select mydf.company, year, date, VARIABLE as variable from mydf left join annual on mydf.company = annual.company and year = substr(date, 7)")

library(dplyr)

mydf %.% 
  mutate(year = d2y(date)) %.%
  left_join(lower.names(annual))

<强> dplyr

setnames

data.table 下面我们可以使用data.table&#39; s annual我们是否愿意修改setNames,但是这里选择了非相反,破坏性的library(data.table) key <- c("company", "year") mydt <- setkeyv(data.table(mydf)[, year := d2y(date)], key) data.table(lower.names(annual), key = key)[mydt]

{{1}}