根据条件将data.table列移至行

时间:2018-11-28 14:29:40

标签: r

我有一个大的data.table,它的设置如下:

ID Line.Rec Line.D.Amount Line.Desc Line1.Record Line1.D.Amount Line1.C.Amount Line2.Rec
1  1        100           test      2            500            200            3
2  1        200           testb     2            800            100            3
3  1        600           testc     2            900            500            NA

每个事件/行都包含一个ID和其他静态列,例如Eventdate。但是,线路数量不尽相同(可能从1到99)。行还包含不同数量的列。这些行不是固定的,某些文件的行与此行不同。因此,我必须使用列名而不是位置。

我希望data.table看起来像这样:

ID Record D.Amount C.Amount Description
1  1      100      0        test
1  2      500      200
1  3      0        0        
2  1      200               testb
2  2      800      100    
2  3      0        0  
3  1      600      0        testc
3  2      900      500      

该解决方案需要确保与名称的第一部分(line。,line1,.2,... line99。)匹配的任何列都包含在正确的行中。如图所示,需要包括ID行(和EventDate),以确保我可以跟踪哪些行属于同一行。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这不是一个问题。您可能需要考虑更改标签。这应该可以帮助您入门:

library(data.table)
dt <- fread("ID Line.Rec Line.D.Amount Line.Desc Line1.Record Line1.D.Amount Line1.C.Amount Line2.Rec
1  1        100           test      2            500            200            3
2  1        200           testb     2            800            100            3
3  1        600           testc     2            900            500            NA")
#ensure that relevant columns share the same names
setnames(dt, gsub("Rec$", "Record", names(dt)))

#identify which columns forms a sub dataset
otherCols <- setdiff(names(dt), "ID")
groupCols <- split(otherCols, sapply(strsplit(otherCols, "\\."), `[`, 1))
newCols <- sapply(names(groupCols), 
    function(x) gsub(paste0(x, "."), "", groupCols[[x]]))

#take sub columns of original dataset by group    
subDataLs <- lapply(names(groupCols),
    function(x) setnames(dt[, c("ID", groupCols[[x]]), with=FALSE], 
        c("ID", newCols[[x]]))
)

#rbind sub datasets
output <- rbindlist(subDataLs, use.names=TRUE, fill=TRUE)

#format to desired output
cols <- names(output)[sapply(output, is.numeric)]
output[, (cols) := replace(.SD, is.na(.SD), 0), .SDcols=cols]
cols <- names(output)[sapply(output, is.character)]
output[, (cols) := replace(.SD, is.na(.SD), ""), .SDcols=cols]

输出:

   ID Record D.Amount  Desc C.Amount
1:  1      1      100  test        0
2:  2      1      200 testb        0
3:  3      1      600 testc        0
4:  1      2      500            200
5:  2      2      800            100
6:  3      2      900            500
7:  1      3        0              0
8:  2      3        0              0
9:  3      0        0              0