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