【问题标题】:Suffixes in merge in RR中合并的后缀
【发布时间】:2015-09-08 08:25:56
【问题描述】:

我有两个需要合并的数据框,它们有共同的列名。 合并后,我想对具有相同名称的列名求和,并且只保留一列。合并添加了我需要事先删除的后缀(.x 和 .y)。我使用下面的代码执行此操作,它可以工作(为简洁起见,省略了求和部分)。这有效:

> x=data.frame(c("2015-05-31","2015-06-30","2015-07-31"),c(100,200,150))
> colnames(x)=c("Date","AAPL")
> x[,1]=as.Date(x[,1],origin="1970-01-01")
> 
> x
        Date AAPL
1 2015-05-31  100
2 2015-06-30  200
3 2015-07-31  150
> 
> y=data.frame(c("2015-05-31","2015-06-30","2015-07-31"),c(3000,8000,2000))
> colnames(y)=c("Date","AAPL")
> y[,1]=as.Date(y[,1],origin="1970-01-01")
> 
> 
> 
> 
> 
> tt=merge(x,y,by='Date',all=TRUE)
> 
> rename=colnames(tt)
> rename=gsub(".x","",rename,fixed=TRUE)
> rename=gsub(".y","",rename,fixed=TRUE)
> colnames(tt)= c(rename)
> 
> tt
        Date AAPL AAPL
1 2015-05-31  100 3000
2 2015-06-30  200 8000
3 2015-07-31  150 2000

但是,我想省略重命名部分,并且我尝试了空后缀:

> tt=merge(x,y,by='Date',all=TRUE)
> tt=merge(x,y,by='Date',all=TRUE,suffixes = c("",""))
Warning message:
In merge.data.frame(x, y, by = "Date", all = TRUE, suffixes = c("",  :
  column name ‘AAPL’ is duplicated in the result
> tt
        Date AAPL AAPL
1 2015-05-31  100 3000
2 2015-06-30  200 8000
3 2015-07-31  150 2000

我收到上面显示的错误消息,但这也有效。问题是,如果我将带有后缀 = c("","") 的代码放入函数中,则会收到错误消息并且不会生成数据帧 tt。知道如何解决这个问题吗?

函数如下:

out=function(){
tt=merge(shares,spin,by='Date',all=TRUE,suffixes = c("",""))
tt=merge(tt,ma5,by='Date',all=TRUE,suffixes = c("",""))
return(tt)
}

out()

【问题讨论】:

  • 为什么需要去掉后缀?对我来说听起来像是一个 XY 问题,我认为应该避免使用双列名。
  • 因为,正如文中所说,我只对同名的列名进行总结。
  • 但我认为这将是一个更好的解决问题,使用正则表达式相当容易。一般来说,当事情抛出这样的错误或警告时,这表明可能有更好的解决方案。为您打造一款。

标签: r function merge


【解决方案1】:

编辑数据,添加一个双列和一个单列。

x=data.frame(Date= as.Date(c("2015-05-31","2015-06-30","2015-07-31")),
             AAPL=c(100,200,150),
             v2=1:3,
             v3=1:3)

y=data.frame(Date=as.Date(c("2015-05-31","2015-06-30","2015-07-31")),
             AAPL=c(3000,8000,2000),
             v2=1:3)

方法 1:使用 plyr 中的 rbind.fill,然后使用 sum 作为聚合函数进行 dcast(缺失已通过熔化删除,您要如何处理取决于数据)

library(reshape2)
library(plyr)
tt1 <- melt(rbind.fill(x,y),id.var="Date",na.rm=T)
res <- dcast(data=tt1, Date~variable,fun.aggregate = sum)
> res
        Date AAPL v2 v3
1 2015-05-31 3100  2  1
2 2015-06-30 8200  4  2
3 2015-07-31 2150  6  3

方法 2,如果你真的想使用合并(这可能会更短,但我没有直接看到如何)

tt=merge(x,y,by='Date',all=TRUE)
merged_pattern <- "\\.[x|y]"
#vector of columns you need to sum because they are double
cols_to_sum <- unique(gsub(merged_pattern,"",
                    grep(merged_pattern,colnames(tt),value=T)))

res <- do.call("cbind", list(tt[,!grepl(merged_pattern,colnames(tt))]
                             ,sapply(cols_to_sum, function(x){
  rowSums(tt[,grepl(x,colnames(tt))])
}))
)
res

> res
        Date v3 AAPL v2
1 2015-05-31  1 3100  2
2 2015-06-30  2 8200  4
3 2015-07-31  3 2150  6

【讨论】:

  • 感谢您的详细解答。您能否详细说明错误:找不到对象'merged_pa​​ttern'?
  • 我很抱歉;这是一个在复制粘贴中丢失的正则表达式。我已经编辑了答案。
【解决方案2】:

我们可以使用 {powerjoin} 非常简洁地解决这个问题

library(powerjoin)
power_left_join(x, y, by = "Date", conflict = `+`)
#         Date AAPL
# 1 2015-05-31 3100
# 2 2015-06-30 8200
# 3 2015-07-31 2150

【讨论】:

    猜你喜欢
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2020-02-13
    • 2020-10-27
    相关资源
    最近更新 更多