У меня есть этот df1:
A B C
1 2 3
5 7 9
Где A B C
- имена столбцов.
У меня есть другой df2 с одним столбцом:
A
1
2
3
4
Я хотел бы добавить df2 для каждого столбца df1, создавая этот окончательный кадр данных:
A B C
1 2 3
5 7 9
1 1 1
2 2 2
3 3 3
4 4 4
Это возможно сделать?
9 ответов
data.frame(sapply(df1, c, unlist(df2)), row.names = NULL)
# A B C
#1 1 2 3
#2 5 7 9
#3 1 1 1
#4 2 2 2
#5 3 3 3
#6 4 4 4
< Сильный > DATA
df1 = structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
df2 = structure(list(A = 1:4), .Names = "A", class = "data.frame", row.names = c(NA,
-4L))
Вот базовый метод R с rbind
, rep
и setNames
:
rbind(dat, setNames(data.frame(rep(dat1, ncol(dat))), names(dat)))
A B C
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4
Редактировать: оказывается data.frame
не обязательно:
rbind(dat, setNames(rep(dat1, ncol(dat)), names(dat)))
Буду работать.
< Сильный > данные
dat <-
structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
dat1 <-
structure(list(A = 1:4), .Names = "A", row.names = c(NA, -4L),
class = "data.frame")
Мы можем скопировать df2
для количества столбцов df1
, снять его, а затем rbind
.
rbind(df1, unname(rep(df2, ncol(df1))))
# A B C
# 1 1 2 3
# 2 5 7 9
# 3 1 1 1
# 4 2 2 2
# 5 3 3 3
# 6 4 4 4
Данных:
df1 <- structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
df2 <- structure(list(A = 1:4), .Names = "A", row.names = c(NA, -4L), class = "data.frame")
Я просто люблю R, вот еще одно Base R
решение, но с mapply
:
data.frame(mapply(c, df1, df2))
< Сильный > Результат :
A B C
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4
< Сильный > Примечание :
Не нужно иметь дело с именами, как почти во всех других решениях ... Ключ к тому, почему это работает, заключается в том, что mapply
вызывает FUN для значений ... [каждого элемента] (повторяется до длины самого длинного ... [элемент] "(см. ?mapply
). Другими словами, df2$A
рециркулируется во все столбцы df1
.
< Сильный > Данные :
df1 = structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
df2 = structure(list(A = 1:4), .Names = "A", row.names = c(NA, -4L), class = "data.frame")
Данных:
df1 <- data.frame(A=c(1,5),
B=c(2,7),
C=c(3,9))
df2 <- data.frame(A=c(1,2,3,4))
Решение:
df2 <- matrix(rep(df2$A, ncol(df1)), ncol=ncol(df1))
colnames(df2) <- colnames(df1)
rbind(df1,df2)
Результат:
A B C 1 1 2 3 2 5 7 9 3 1 1 1 4 2 2 2 5 3 3 3 6 4 4 4
Решение из purrr
, которое использует map_dfc
для циклического перебора всех столбцов в df1
, чтобы объединить все элементы с df2$A
.
library(purrr)
map_dfc(df1, ~c(., df2$A))
# A tibble: 6 x 3
A B C
<int> <int> <int>
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4
Данные
df1 <- structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
df2 <- structure(list(A = 1:4), .Names = "A", class = "data.frame",
row.names = c(NA, -4L))
Для полноты, вот data.table
подход, который не требует обработки имен столбцов:
library(data.table)
setDT(df1)[, lapply(.SD, c, df2$A)]
A B C 1: 1 2 3 2: 5 7 9 3: 1 1 1 4: 2 2 2 5: 3 3 3 6: 4 4 4
Обратите внимание, что OP описал df2
, чтобы он состоял только из одного столбца.
Существует также базовая версия R этого подхода:
data.frame(lapply(df1, c, df2$A))
A B C 1 1 2 3 2 5 7 9 3 1 1 1 4 2 2 2 5 3 3 3 6 4 4 4
Это похоже на подход d.b, но не требуется для работы с именами столбцов.
Мы можем использовать base R
методы
rbind(df1, setNames(as.data.frame(do.call(cbind, rep(list(df2$A), 3))), names(df1)))
# A B C
#1 1 2 3
#2 5 7 9
#3 1 1 1
#4 2 2 2
#5 3 3 3
#6 4 4 4
Данные
df1 <- structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A",
"B", "C"), class = "data.frame", row.names = c(NA, -2L))
df2 <- structure(list(A = 1:4), .Names = "A", class = "data.frame",
row.names = c(NA, -4L))
По аналогии с превосходным ответом @ useR Base R, вот tidyverse
решение:
library(purrr)
map2_df(df1, df2, c)
A B C 1 1 2 3 2 5 7 9 3 1 1 1 4 2 2 2 5 3 3 3 6 4 4 4
Вот несколько других (менее желательных) вариантов, когда я впервые ответил на этот вопрос.
library(dplyr)
bind_rows(df1, df2 %>% mutate(B=A, C=A))
Или, если мы хотим динамически получить количество столбцов и их имена из df1:
bind_rows(df1,
df2[,rep(1,ncol(df1))] %>% setNames(names(df1)))
И еще один метод Base R:
rbind(df1, setNames(df2[,rep(1,ncol(df1))], names(df1)))
Похожие вопросы
Связанные вопросы
Новые вопросы
r
R - это бесплатный язык программирования с открытым исходным кодом и программная среда для статистических вычислений, биоинформатики, визуализации и общих вычислений. Пожалуйста, предоставьте минимальные и воспроизводимые примеры вместе с желаемым результатом. Используйте dput () для данных и укажите все небазовые пакеты с вызовами library (). Не вставляйте изображения для данных или кода, вместо этого используйте блоки кода с отступом. По вопросам, связанным со статистикой, используйте https://stats.stackexchange.com.