r расширить столбцы data.table, заполнив значения строк - PullRequest
2 голосов
/ 22 марта 2019

У меня есть data.table:

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

Я хотел бы получить новый файл data.table со следующей структурой:

       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,])

Как создать аналогичный (кроме использования для циклов) data.table p2 с 10001 столбцами, когда у меня есть входной data.table p с 10000 строками?

Любая помощь приветствуется.

Ответы [ 4 ]

3 голосов
/ 22 марта 2019

Вот еще один вариант использования 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

Обновление

@ Фрэнк указал в комментариях, что 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

Чтобы получить порядок col по желанию 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
2 голосов
/ 22 марта 2019
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
2 голосов
/ 22 марта 2019

Вот еще один вариант, похожий на 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
2 голосов
/ 22 марта 2019

Мы можем использовать 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, .)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...