new*_*r_7 3 r subset data.table dcast
我有一个 2200 万个观察行的数据表,其形式如下:
`dt <- data.table(
firm_id = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2),
metric = c("AN_BILANT", "OPEX", "CAPEX","AN_BILANT","OPEX", "CAPEX", "AN_BILANT", "OPEX", "CAPEX", "AN_BILANT","OPEX", "CAPEX"),
value = c(2013, 10, 3,2014, 11, 5, 2007, 25, 10, 2009, 23, 7)
)`
Run Code Online (Sandbox Code Playgroud)
我想使用 data.table 生成以下输出
`output_dt <- data.table(
firm_id = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2),
metric = c("OPEX", "CAPEX","OPEX", "CAPEX", "OPEX", "CAPEX", "OPEX", "CAPEX"),
AN_BILANT = c(2013, 2013, 2014, 2014, 2007, 2007, 2009)
value = c( 10, 3,11, 5, 25, 10,23, 7)
)
`
Run Code Online (Sandbox Code Playgroud)
我最初尝试了以下方法:
dcast(dt[metric == "AN_BILANT"], firm_id ~ metric, value.var = "value", fun.aggregate = function(x) x)
但我收到以下错误
错误:聚合函数应采用向量输入并返回单个值(长度=1)。然而,函数返回 length!=1。该值必须用于填充任何缺失的组合,因此长度必须=1。通过显式设置“fill”参数来覆盖,或者修改您的函数以适当地处理这种情况。
我也尝试过
dcast.data.table(dt[, N:=1:.N, metric], firm_id~metric, subset = (metric=="AN_BILANT") )
我在这里收到警告
缺少聚合函数,默认为“length”
我喜欢 akrun 的方法,但如果数据迫使您选择替代方案(以防cumsum
对数据排序过于敏感),您可以尝试如下所示的 dcast/melt 方法。请注意,由于firm_id
不只包含每个变量之一metric
,因此我们需要临时添加另一个变量,以便在初始过程中不会过度减少dcast
。
library(data.table)
dcast(DT[, grp := seq_len(.N), by = .(firm_id, metric)],
firm_id + grp ~ metric, value.var = "value")[, grp := NULL] |>
melt(c("firm_id", "AN_BILANT"), variable.name = "metric")
# firm_id AN_BILANT metric value
# <num> <num> <fctr> <num>
# 1: 1 2013 CAPEX 3
# 2: 1 2014 CAPEX 5
# 3: 2 2007 CAPEX 10
# 4: 2 2009 CAPEX 7
# 5: 1 2013 OPEX 10
# 6: 1 2014 OPEX 11
# 7: 2 2007 OPEX 25
# 8: 2 2009 OPEX 23
Run Code Online (Sandbox Code Playgroud)
当然,行的顺序不相同,但双重重塑通常不能保证这一点。