R rbind a dataframe of dataframes - PullRequest
       37

R rbind a dataframe of dataframes

4 голосов
/ 22 июня 2019

Как можно объединить фрейм данных, который содержит один или несколько фреймов данных среди своих столбцов.Например:

df <- data.frame(a=1:3)
df$df <- data.frame(a=1:3)  
rbind( df, df)

Ошибка в row.names<-.data.frame (*tmp*, значение = значение):
повторяющиеся 'row.names' не допускаются. Дополнительно: Предупреждение: неуникальные значения при установке 'row.names': '1', '2', '3'

library(dplyr)
bind_rows(list(df,df))

Ошибка: аргумент 2 не может быть списком, содержащим фреймы данных

Ответы [ 3 ]

1 голос
/ 23 июня 2019

Проблема здесь, кажется, не в другом data.frame внутри фрейма данных, а в неуникальном rownames в результате.Если вы убедились, что имена строк уникальны после rbind - это должно сработать:

df1 <- data.frame(a=1:3)
df2 <- data.frame(a=1:3)
df1$df <- data.frame(a=1:3, row.names=letters[1:3])
df2$df <- data.frame(a=1:3, row.names=LETTERS[1:3])

> res <- rbind(df1, df2)
> res
  a a
1 1 1
2 2 2
3 3 3
4 1 1
5 2 2
6 3 3

> res$df
  a
a 1
b 2
c 3
A 1
B 2
C 3

Кажется, проблема в том, что rbind корректирует имена строк для двух объединяемых фреймов данных, но не корректируетимена строк для data.frames внутри data.frames.

1 голос
/ 23 июня 2019

Мы можем list фреймы данных, затем использовать mapply для различной обработки типов столбцов: stack для векторов и do.call(rbind) для data.frame с.

L <- mget(ls(pattern="df\\."))  # or list(df.1, df.2, df.3)
res <- data.frame(a=stack(mapply(`[`, L, 1))[[1]])
res$df <- do.call(rbind, mapply(`[`, L, 2))
res
#   a a
# 1 1 1
# 2 2 2
# 3 3 3
# 4 4 4
# 5 5 5
# 6 6 6
# 7 7 7
# 8 8 8
# 9 9 9
str(res)
# 'data.frame': 9 obs. of  2 variables:
#   $ a : int  1 2 3 4 5 6 7 8 9
# $ df:'data.frame':    9 obs. of  1 variable:
#   ..$ a: int  1 2 3 4 5 6 7 8 9

Данные

df.1 <- structure(list(a = 1:3, df = structure(list(a = 1:3), class = "data.frame", row.names = c(NA, 
-3L))), row.names = c(NA, -3L), class = "data.frame")
df.2 <- structure(list(a = 4:6, df = structure(list(a = 4:6), class = "data.frame", row.names = c(NA, 
-3L))), row.names = c(NA, -3L), class = "data.frame")
df.3 <- structure(list(a = 7:9, df = structure(list(a = 7:9), class = "data.frame", row.names = c(NA, 
-3L))), row.names = c(NA, -3L), class = "data.frame")
1 голос
/ 23 июня 2019

Один из вариантов: rep лицензировать df дважды (или более) вместо rbind -ing;это автоматически создаст не дублированный row.names.Попробуйте это:

df[rep(seq_len(nrow(df)), 2), ]
# output
    a a
1   1 1
2   2 2
3   3 3
1.1 1 1
2.1 2 2
3.1 3 3

Тот же процесс с использованием dplyr даст вам более интересное row.names:

library(dplyr)
df %>% slice(rep(row_number(), 2))
# output
  a a
1 1 1
2 2 2
3 3 3
4 1 1
5 2 2
6 3 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...