我有一个大的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),以确保我可以跟踪哪些行属于同一行。
有什么想法吗?
答案 0 :(得分:0)
这不是一个data.table问题。您可能需要考虑更改标签。这应该可以帮助您入门:
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