簡體   English   中英

通過填充行值來擴展data.table列

[英]r extend data.table columns by filling row values

我有一個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,])

當我輸入帶有10000行的data.table p時,如何創建一個類似的(除了使用for循環)data.table p2和10001列?

任何幫助表示贊賞。

這是另一個選項,使用rbindlistcbind on 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可以采用兩個數據幀的不等行數。 在這種情況下,具有較少行號的數據幀將被“回收”。 所以我們不需要reprbindlist ,下面是更新的代碼。

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所需的col順序,一個選項是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

我們可以使用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

或者使用transposebind_cols

purrr::transpose(p1) %>% 
    bind_cols %>% 
    rowr::cbind.fill(p1, .)

這是另一種選擇,類似於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM