我有一个数据表:
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,])
当我输入具有10000行的data.table p时,如何创建类似的(除了用于循环之外)具有10001列的data.table p2?
感谢您的帮助。
答案 0 :(得分:3)
这是对转置数据帧使用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
答案 1 :(得分:2)
我们可以使用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, .)
答案 2 :(得分:2)
这是另一个选项,类似于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
答案 3 :(得分:2)
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