R: привязать кадры данных с другим именем столбца

У меня есть 12 кадров данных, каждый из которых содержит 6 столбцов: 5 имеют одно и то же имя, 1 - другое. Затем, когда я вызываю rbind(), я получаю:

Error in match.names(clabs, names(xi)) : 
  names do not match previous names

Колонка, которая отличается: "goal1Completions". Есть 12 целей. Завершения... это: "goal1Completions", "goal2Completions", "goal3Completions"... и т.д.

Лучший способ, о котором я могу думать, - переименование каждого столбца в каждом кадре данных на "GoalsCompletions", а затем использование "rbind()".

Есть ли более простой способ?

Посмотрите на Google, я нашел этот пакет: " gtools". Он имеет функцию, называемую "smartbind". Однако после использования smartbind() я хочу увидеть кадр данных с помощью "View()", мой сеанс R сбой...

Мои данные (пример первого фрейма данных):

       date      source     medium   campaign   goal1Completions    ad.cost           Goal
1   2014-10-01  (direct)    (none)   (not set)          0           0.0000            Vida
2   2014-10-01   Master      email     CAFRE            0           0.0000            Vida
3   2014-10-01  apeseg      referral (not set)          0           0.0000            Vida

Ответ 1

Вы можете использовать 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

Update

На основе имен объектов из 12 наборов данных (то есть "Goal1_Costo", "Goal2_Costo",..., "Goal12_Costo" ),

 nm1 <- paste(paste0('Goal', 1:12), 'Costo', sep="_")
 #or using `sprintf`
 #nm1 <- sprintf('%s%d_%s', 'Goal', 1:12, 'Costo')
 rbindlist(mget(nm1))

Ответ 2

Мое любимое использование mapply:

Примеры данных

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

и b

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:

> 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

И на основе комментария @Marat ниже:

Вы также можете сделать data.frame(mapply(c, a, b, SIMPLIFY=FALSE)) или, альтернативно, data.frame(Map(c,a,b)), чтобы избежать преобразования с двойной матрицей данных.

Ответ 3

Я бы переименовал столбцы. Это очень легко с 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)

или

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

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

rbind(df1,setnames(df2,names(df1)))

Результат:

   one two three
1    1  11    21
2    2  12    22
3    3  13    23
4    4  14    24
5    5  15    25
6    6  16    26
7    7  17    27
8    8  18    28
9    9  19    29
10  10  20    30
11  31  41    51
12  32  42    52
13  33  43    53
14  34  44    54
15  35  45    55
16  36  46    56
17  37  47    57
18  38  48    58
19  39  49    59
20  40  50    60

Ответ 4

Вот возможное решение Tidyverse. Я создал 3 примера данных на основе вашего описания ваших данных.

df1 <- read.table(text ="date,source,medium,campaign,goal1Completions,ad.cost,Goal
2014-10-01,(direct),(none),(notset),1,0.0000,Vida
2014-10-01,Master,email,CAFRE,2,0.0000,Vida
2014-10-01,apeseg,referral,(not set),3,0.0000,vida",sep = ",",header=TRUE) 

df2 <- read.table(text ="date,source,medium,campaign,goal2Completions,ad.cost,Goal
2014-10-01,(direct),(none),(notset),4,0.0000,Vida
2014-10-01,Master,email,CAFRE,5,0.0000,Vida
2014-10-01,apeseg,referral,(not set),6,0.0000,vida",sep = ",",header=TRUE) 

df3 <- read.table(text ="date,source,medium,campaign,goal3Completions,ad.cost,Goal
2014-10-01,(direct),(none),(notset),7,0.0000,Vida
2014-10-01,Master,email,CAFRE,8,0.0000,Vida
2014-10-01,apeseg,referral,(not set),9,0.0000,vida",sep = ",",header=TRUE) 

> df1
        date   source   medium  campaign goal1Completions ad.cost Goal
1 2014-10-01 (direct)   (none)  (notset)                1       0 Vida
2 2014-10-01   Master    email     CAFRE                2       0 Vida
3 2014-10-01   apeseg referral (not set)                3       0 vida
> df2
        date   source   medium  campaign goal2Completions ad.cost Goal
1 2014-10-01 (direct)   (none)  (notset)                4       0 Vida
2 2014-10-01   Master    email     CAFRE                5       0 Vida
3 2014-10-01   apeseg referral (not set)                6       0 vida
> df3
        date   source   medium  campaign goal3Completions ad.cost Goal
1 2014-10-01 (direct)   (none)  (notset)                7       0 Vida
2 2014-10-01   Master    email     CAFRE                8       0 Vida
3 2014-10-01   apeseg referral (not set)                9       0 vida

library(dplyr)
library(tidyselect)
library(purrr)

bind_rows(df1,df2,df3) %>%
   mutate(goalCompletions = reduce(select_at(.,vars(matches("goal[[:digit:]]+Completions"))),coalesce)) %>%
   select_at(vars(-matches("goal[[:digit:]]+Completions")))

        date   source   medium  campaign ad.cost Goal goalCompletions
1 2014-10-01 (direct)   (none)  (notset)       0 Vida               1
2 2014-10-01   Master    email     CAFRE       0 Vida               2
3 2014-10-01   apeseg referral (not set)       0 vida               3
4 2014-10-01 (direct)   (none)  (notset)       0 Vida               4
5 2014-10-01   Master    email     CAFRE       0 Vida               5
6 2014-10-01   apeseg referral (not set)       0 vida               6
7 2014-10-01 (direct)   (none)  (notset)       0 Vida               7
8 2014-10-01   Master    email     CAFRE       0 Vida               8
9 2014-10-01   apeseg referral (not set)       0 vida               9