У меня есть таблица данных:
library(data.table)
p1 = data.table(a = c(10.34,25.87,53.2), b=c(15.3,183.2,34.8))
print(p1)
a b
1: 10.34 15.3
2: 25.87 183.2
3: 53.20 34.8
Я хотел бы получить новую таблицу данных со следующей структурой:
a b a1 b1 a2 b2 a3 b3
1: 10.34 15.3 10.34 15.3 25.87 183.2 53.2 34.8
2: 25.87 183.2 10.34 15.3 25.87 183.2 53.2 34.8
3: 53.20 34.8 10.34 15.3 25.87 183.2 53.2 34.8
Мое текущее решение:
p2 = cbind(p,p[1,],p[2,],p[3,])
Как мне создать аналогичную (кроме использования циклов for) data.table p2 с 10001 столбцом, когда у меня есть входная data.table p с 10000 строк?
Любая помощь приветствуется.
Мы можем использовать shift
out <- cbind(p1, p1[, shift(.SD, type = 'lead',
n = c(0, seq_len(.N-1)))][rep(1, nrow(p1))])
setnames(out, make.unique(c(names(p1), rep(names(p1), each = nrow(p1)))))
или с tidyverse
library(tidyverse)
pmap_dfc(p1, list) %>%
uncount(nrow(p1))
Если нам нужны исходные данные, а также
pmap_dfc(p1, list) %>%
rowr::cbind.fill(p1, .)
# a b a b a1 b1 a2 b2
#1 10.34 15.3 10.34 15.3 25.87 183.2 53.2 34.8
#2 25.87 183.2 10.34 15.3 25.87 183.2 53.2 34.8
#3 53.20 34.8 10.34 15.3 25.87 183.2 53.2 34.8
Или с transpose
и bind_cols
purrr::transpose(p1) %>%
bind_cols %>%
rowr::cbind.fill(p1, .)
Вот еще один вариант использования rbindlist
и cbind
на rep
для транспонированного фрейма данных.
library(data.table)
cbind(p1, rbindlist(rep(list(data.table(t(unlist(p1)))), times = nrow(p1))))
# a b a1 a2 a3 b1 b2 b3
# 1: 10.34 15.3 10.34 25.87 53.2 15.3 183.2 34.8
# 2: 25.87 183.2 10.34 25.87 53.2 15.3 183.2 34.8
# 3: 53.20 34.8 10.34 25.87 53.2 15.3 183.2 34.8
Обновлять
@Frank указал в комментариях, что cbind
может принимать неравные номера строк двух кадров данных. В этом случае фрейм данных с меньшим количеством строк будет «переработан». Так что нам не нужны rep
или rbindlist
, а ниже приведен обновленный код.
cbind(p1, data.table(t(unlist(p1))))
# a b a1 a2 a3 b1 b2 b3
# 1: 10.34 15.3 10.34 25.87 53.2 15.3 183.2 34.8
# 2: 25.87 183.2 10.34 25.87 53.2 15.3 183.2 34.8
# 3: 53.20 34.8 10.34 25.87 53.2 15.3 183.2 34.8
Чтобы получить желаемый OP порядок цветов, один из вариантов: setcolorder
:
cbind(p1, setcolorder(data.table(t(unlist(p1))), order(row(p1))) )
# a b a1 b1 a2 b2 a3 b3
# 1: 10.34 15.3 10.34 15.3 25.87 183.2 53.2 34.8
# 2: 25.87 183.2 10.34 15.3 25.87 183.2 53.2 34.8
# 3: 53.20 34.8 10.34 15.3 25.87 183.2 53.2 34.8
Вот еще один вариант, похожий на www
:
> cbind(p1, matrix(rep(unlist(p1), nrow(p1)), nrow = nrow(p1), byrow=T))
a b V1 V2 V3 V4 V5 V6
1: 10.34 15.3 10.34 25.87 53.2 15.3 183.2 34.8
2: 25.87 183.2 10.34 25.87 53.2 15.3 183.2 34.8
3: 53.20 34.8 10.34 25.87 53.2 15.3 183.2 34.8
cbind(p1, do.call(cbind, split(p1, 1:nrow(p1))))
# a b 1.a 1.b 2.a 2.b 3.a 3.b
# 1: 10.34 15.3 10.34 15.3 25.87 183.2 53.2 34.8
# 2: 25.87 183.2 10.34 15.3 25.87 183.2 53.2 34.8
# 3: 53.20 34.8 10.34 15.3 25.87 183.2 53.2 34.8