使用不同列名的rbind数据帧

使用不同列名的rbind数据帧,r,dataframe,rbind,R,Dataframe,Rbind,我有12个数据帧,每个数据帧包含6列:5个名称相同,1个不同。然后,当我调用rbind()时,我得到: Error in match.names(clabs, names(xi)) : names do not match previous names 不同的一栏是:“目标完成”。有12个进球完成。。。它们是:“目标完成”、“目标完成”、“目标完成”。。。等等 我能想到的最好的方法是:将每个数据帧中的每一列重命名为“GoalsCompletions”,然后使用“rbind() 有没有更简

我有12个数据帧,每个数据帧包含6列:5个名称相同,1个不同。然后,当我调用
rbind()
时,我得到:

Error in match.names(clabs, names(xi)) : 
  names do not match previous names
不同的一栏是:“目标完成”。有12个进球完成。。。它们是:“目标完成”、“目标完成”、“目标完成”。。。等等

我能想到的最好的方法是:将每个数据帧中的每一列重命名为“GoalsCompletions”,然后使用“rbind()

有没有更简单的方法

在Google上查找,发现此软件包:“”。它有一个名为“smartbind”的函数。但是,在使用smartbind()后,我希望看到带有“View()”的数据帧,我的R会话崩溃

我的数据(第一个数据帧的示例):


我将重命名这些列。如果列的顺序相同,则使用
names()
非常容易

df1 <- data.frame(one=1:10,two=11:20,three=21:30)

df2 <- data.frame(four=31:40,five=41:50,six=51:60)

names(df2)<-names(df1)

rbind(df1,df2)

我最喜欢使用的
mapply

> mapply(c, a,b)    #or as.data.frame(mapply(c, a,b)) for a data.frame
              a         b
 [1,] 0.8403348 0.1579255
 [2,] 0.4759767 0.8182902
 [3,] 0.8091875 0.1080651
 [4,] 0.9846333 0.7035959
 [5,] 0.2153991 0.8744136
 [6,] 0.7604137 0.9753853
 [7,] 0.7553924 0.1210260
 [8,] 0.7315970 0.6196829
 [9,] 0.5619395 0.1120331
[10,] 0.5711995 0.7252631
示例数据

a <- data.frame(a=runif(5), b=runif(5))
> a
          a         b
1 0.8403348 0.1579255
2 0.4759767 0.8182902
3 0.8091875 0.1080651
4 0.9846333 0.7035959
5 0.2153991 0.8744136
根据@Marat的以下评论:


您还可以执行
data.frame(mapply(c,a,b,SIMPLIFY=FALSE))
data.frame(Map(c,a,b))
以避免双重数据。frame-matrix转换

您可以使用采用不同列名的
rbindlist
。使用@LyzandeR的数据

library(data.table) #data.table_1.9.5
rbindlist(list(a,b))
#            a         b
# 1: 0.8403348 0.1579255
# 2: 0.4759767 0.8182902
# 3: 0.8091875 0.1080651
# 4: 0.9846333 0.7035959
# 5: 0.2153991 0.8744136
# 6: 0.7604137 0.9753853
# 7: 0.7553924 0.1210260
# 8: 0.7315970 0.6196829
# 9: 0.5619395 0.1120331
#10: 0.5711995 0.7252631
使现代化 基于12个数据集的对象名称(即“Goal1_-Costo”、“Goal2_-Costo”、“Goal12_-Costo”)


nm1这里有一个可能的tidyverse解决方案。我根据您对数据帧的描述创建了3个示例数据帧

df1-df3
日期来源中期活动目标完成广告成本目标
1 2014-10-01(直接)(无)(未设定)7 0维达
2 2014-10-01主电子邮件CAFRE 8 0 Vida
3 2014-10-01 apeseg转诊(未设置)9 0 vida
图书馆(dplyr)
图书馆(tidyselect)
图书馆(purrr)
绑定行(df1、df2、df3)%>%
mutate(goalCompletions=reduce(在(,vars(匹配(“目标[:数字:]]+完成”))处选择),coalesce))%>%
选择(变量(-matches)(“目标[:数字:]+完成”))
日期来源媒体活动广告。成本目标完成
1 2014-10-01(直接)(无)(未设定)0 Vida 1
2 2014-10-01主电子邮件CAFRE 0 Vida 2
3 2014-10-01 apeseg转诊(未设置)0 vida 3
4 2014-10-01(直接)(无)(未设定)0 Vida 4
5 2014-10-01主电子邮件CAFRE 0 Vida 5
6 2014-10-01 apeseg转诊(未设置)0 vida 6
7 2014-10-01(直接)(无)(未设定)0 Vida 7
8 2014-10-01主电子邮件CAFRE 0 Vida 8
9 2014-10-01 apeseg转诊(未设置)0 vida 9

如果您有具有不同列名的
data.frame
s,则另一种基本R方法:

# Create a list of data frames
df_list <- list()
df_list[[1]] <- data.frame(x = 1, y = paste0("y1", 1:3))
df_list[[2]] <- data.frame(x = 2, y = paste0("y2", 1:4))
df_list[[3]] <- data.frame(x = 3, y = paste0("y3", 1:5), z = "z3")
df_list
#> [[1]]
#>   x   y
#> 1 1 y11
#> 2 1 y12
#> 3 1 y13
#> 
#> [[2]]
#>   x   y
#> 1 2 y21
#> 2 2 y22
#> 3 2 y23
#> 4 2 y24
#> 
#> [[3]]
#>   x   y  z
#> 1 3 y31 z3
#> 2 3 y32 z3
#> 3 3 y33 z3
#> 4 3 y34 z3
#> 5 3 y35 z3

# This works when the column names are the same
do.call(rbind, df_list[1:2])
#>   x   y
#> 1 1 y11
#> 2 1 y12
#> 3 1 y13
#> 4 2 y21
#> 5 2 y22
#> 6 2 y23
#> 7 2 y24

# but fails when the column names differ
do.call(rbind, df_list)
#> Error in rbind(deparse.level, ...): numbers of columns of arguments do not match

# This can fill the unmatched columns with NA's without 
# depending on other packages:
Reduce(rbind, Map(function(x) {
  x[, setdiff(unique(unlist(lapply(df_list, colnames))), names(x))] <- NA; 
  return(x)
  }, 
  df_list))
#>    x   y    z
#> 1  1 y11 <NA>
#> 2  1 y12 <NA>
#> 3  1 y13 <NA>
#> 4  2 y21 <NA>
#> 5  2 y22 <NA>
#> 6  2 y23 <NA>
#> 7  2 y24 <NA>
#> 8  3 y31   z3
#> 9  3 y32   z3
#> 10 3 y33   z3
#> 11 3 y34   z3
#> 12 3 y35   z3
#创建数据帧列表
df_列表2 1 y12
#>3 1 y13
#> 
#> [[2]]
#>xy
#>1.2 y21
#>2 y22
#>3.2 y23
#>4.2 y24
#> 
#> [[3]]
#>x y z
#>1 3 y31 z3
#>2 3 y32 z3
#>3 y33 z3
#>4 3 y34 z3
#>5Y35Z3
#当列名相同时,此操作有效
do.呼叫(rbind,df_列表[1:2])
#>xy
#>1 y11
#>2 1 y12
#>3 1 y13
#>4.2 y21
#>5.2 y22
#>6.2 y23
#>7.2 y24
#但在列名不同时失败
do.呼叫(rbind,df_列表)
#>rbind(deparse.level,…)中出错:参数的列数不匹配
#这可以用NA填充不匹配的列,而不需要
#根据其他包:
减少(rbind,Map)(函数(x){
x[,setdiff(唯一(未列出(lappy(df_列表,colnames))),名称(x))]x y z
#>1 y11
#>2 1 y12
#>3 1 y13
#>4.2 y21
#>5.2 y22
#>6.2 y23
#>7.2 y24
#>8 3 y31 z3
#>9 3 y32 z3
#>10 3 y33 z3
#>11 3 y34 z3
#>12 3 y35 z3

它看起来非常聪明。mapply(c,a,b)中的“c”用于连接?它连接“a”,“b”并将列名从“a”中保留下来?您可以通过
data.frame(mapply(c,a,b,SIMPLIFY=FALSE))或
data.frame(Map(c,a,b))避免双重数据.frame-matrix转换
@OmarGonzales是的,这是常用的连接函数,它会保留a中的列名。每次连接元素(即列)最后返回一个矩阵。这可能很危险,因为它会将具有不同列维度的数据帧组合在一起。不过,这将是完美的。我相信一个简单的if语句也可以。虽然时间很晚,但
purrr::map2_df(a,b,c)
将不必包装在
data.frame
中就可以工作,尽管我不知道它是否在内部避免了双重转换。并且,像@MaratTalipov的答案一样,将保留第一个df的类型,而mapply强制(在我的情况下,在混合dbl或date和chr列时对所有字符).OP提到了大约12个数据集。所以可能,
df3 dplyr没有类似的功能?我正在寻找它,如果有人知道,请发布。@OmarGonzales它有
bind_rows
,但列名仍然是个问题。因此,不是2列,而是4列。根据
?bind_rows
行绑定时,列按名称匹配,任何不匹配的值都将用NA填充。
多亏了all,但我结束了使用它,因为它看起来更简单。不过,我需要进一步研究mapplay函数…似乎非常强大。@OmarGonzales使用
rbindlist
的一个优点是速度。请执行以下操作12数据集对象有一些名称模式,即
df1、df2、df3等
最好将它们放在一个列表中,然后再进行rbindlist(即
rbindlist(mget(粘贴0('df',1:12)))
@akrun,是的,模式是:
Goal1\u Costo,Goal2\u Costo,…Goal12\u Costo
。如果您需要更新答案,请更新。@Omar\u Gonzales谢谢,更新了答案
b <- data.frame(c=runif(5), d=runif(5))
> b
          c         d
1 0.7604137 0.9753853
2 0.7553924 0.1210260
3 0.7315970 0.6196829
4 0.5619395 0.1120331
5 0.5711995 0.7252631
> mapply(c, a,b)    #or as.data.frame(mapply(c, a,b)) for a data.frame
              a         b
 [1,] 0.8403348 0.1579255
 [2,] 0.4759767 0.8182902
 [3,] 0.8091875 0.1080651
 [4,] 0.9846333 0.7035959
 [5,] 0.2153991 0.8744136
 [6,] 0.7604137 0.9753853
 [7,] 0.7553924 0.1210260
 [8,] 0.7315970 0.6196829
 [9,] 0.5619395 0.1120331
[10,] 0.5711995 0.7252631
library(data.table) #data.table_1.9.5
rbindlist(list(a,b))
#            a         b
# 1: 0.8403348 0.1579255
# 2: 0.4759767 0.8182902
# 3: 0.8091875 0.1080651
# 4: 0.9846333 0.7035959
# 5: 0.2153991 0.8744136
# 6: 0.7604137 0.9753853
# 7: 0.7553924 0.1210260
# 8: 0.7315970 0.6196829
# 9: 0.5619395 0.1120331
#10: 0.5711995 0.7252631
 nm1 <- paste(paste0('Goal', 1:12), 'Costo', sep="_")
 #or using `sprintf`
 #nm1 <- sprintf('%s%d_%s', 'Goal', 1:12, 'Costo')
 rbindlist(mget(nm1))
# Create a list of data frames
df_list <- list()
df_list[[1]] <- data.frame(x = 1, y = paste0("y1", 1:3))
df_list[[2]] <- data.frame(x = 2, y = paste0("y2", 1:4))
df_list[[3]] <- data.frame(x = 3, y = paste0("y3", 1:5), z = "z3")
df_list
#> [[1]]
#>   x   y
#> 1 1 y11
#> 2 1 y12
#> 3 1 y13
#> 
#> [[2]]
#>   x   y
#> 1 2 y21
#> 2 2 y22
#> 3 2 y23
#> 4 2 y24
#> 
#> [[3]]
#>   x   y  z
#> 1 3 y31 z3
#> 2 3 y32 z3
#> 3 3 y33 z3
#> 4 3 y34 z3
#> 5 3 y35 z3

# This works when the column names are the same
do.call(rbind, df_list[1:2])
#>   x   y
#> 1 1 y11
#> 2 1 y12
#> 3 1 y13
#> 4 2 y21
#> 5 2 y22
#> 6 2 y23
#> 7 2 y24

# but fails when the column names differ
do.call(rbind, df_list)
#> Error in rbind(deparse.level, ...): numbers of columns of arguments do not match

# This can fill the unmatched columns with NA's without 
# depending on other packages:
Reduce(rbind, Map(function(x) {
  x[, setdiff(unique(unlist(lapply(df_list, colnames))), names(x))] <- NA; 
  return(x)
  }, 
  df_list))
#>    x   y    z
#> 1  1 y11 <NA>
#> 2  1 y12 <NA>
#> 3  1 y13 <NA>
#> 4  2 y21 <NA>
#> 5  2 y22 <NA>
#> 6  2 y23 <NA>
#> 7  2 y24 <NA>
#> 8  3 y31   z3
#> 9  3 y32   z3
#> 10 3 y33   z3
#> 11 3 y34   z3
#> 12 3 y35   z3