R 数据中按组划分的不同列中先前行值与当前行值的总和比率。table/frame
Sum ratios of previous rows values over current row value in a different column by groups in R data.table/frame
我的问题希望很容易理解,但用编码术语来说却很重要。一旦我们弄清楚其他人会寻找什么,我将调整标题以获得更多 accurate/general 术语。
我想每天计算一个 HHI(赫芬达尔指数),即按国家/地区计算每个 industry
的平方份额之和。 Value_country
是上一年每个国家/地区的 id
数量,value_country_industry
是上一年每个国家和行业的 id
数量。
计算示例:2017/01/03
上的 HHI 计算为 (3/5)^2 (industry A) + (1/5)^2 (industry B) + (1/5)^2 (industry C) = 0.44
,其中 分母 在相应日期等于 value_country
numerator 是每个行业的最新 value_country_industry
(即份额,但在 当前 日期。这意味着我不能只是工作与 share
列。)
扩展到更大数据(并可能使用 NA
s)的解决方案将是理想的(因此,data.table
标签)。
示例数据
library(data.table)
library(dplyr)
ID <- c("1","2","3","4","5","6")
Date <- c("2017-01-01","2017-01-02", "2017-01-02", "2017-01-02", "2017-01-03","2017-01-02")
Industry <- c("A","A","B","C","A","A")
Country <- c("UK","UK","UK","UK","UK","US")
Value_country<- c(1,4,4,4,5,1)
Value_country_industry<- c(1,2,1,1,3,1)
Share <- c(1,0.5,0.25,0.25,0.6,1)
Desired <- c(1,0.375,0.375,0.375,0.44,1)
dt <- data.frame(id=ID, date=Date, industry=Industry, country=Country, value_country=Value_country, value_country_industry=Value_country_industry, desired_output=Desired)
setDT(dt)[, date := as.Date(date)]
一种方法是将数据范围扩大,以便更容易说明“最近的”value_country_industry”规则。
然后填写并用 0 替换任何 NA。
然后可以跨列计算 HHI,确保无论有多少行业,它都能正常工作。
library(magrittr)
dt_wide <- dt[, -c('desired_output')] %>%
setnames(c('value_country', 'value_country_industry'), c('vc', 'vci')) %>%
dcast(country + date ~ industry, fun.aggregate = last, fill = NA,
value.var = c('vc', 'vci'))
vci_cols <- names(dt_wide) %>% .[grepl('vci', .)]
dt_wide[, (vci_cols) := lapply(.SD, nafill, type = 'locf'), by = 'country',
.SDcols = vci_cols] %>%
setnafill(fill = 0L, cols = 3:length(.))
dt_wide[, num := Reduce('+', .SD ^ 2), .SDcols = patterns('vci_')]
dt_wide[, den := Reduce('pmax', .SD ^ 2), .SDcols = patterns('vc_')]
dt_wide[, hhi := num / den]
dt_wide[, c('num', 'den') := NULL]
dt[dt_wide, hhi := hhi, on = c('country', 'date')]
dt
id date industry country value_country value_country_industry desired_output hhi
1: 1 2017-01-01 A UK 1 1 1.000 1.000
2: 2 2017-01-02 A UK 4 2 0.375 0.375
3: 3 2017-01-02 B UK 4 1 0.375 0.375
4: 4 2017-01-02 C UK 4 1 0.375 0.375
5: 5 2017-01-03 A UK 5 3 0.440 0.440
6: 6 2017-01-02 A US 1 1 1.000 1.000
我的问题希望很容易理解,但用编码术语来说却很重要。一旦我们弄清楚其他人会寻找什么,我将调整标题以获得更多 accurate/general 术语。
我想每天计算一个 HHI(赫芬达尔指数),即按国家/地区计算每个 industry
的平方份额之和。 Value_country
是上一年每个国家/地区的 id
数量,value_country_industry
是上一年每个国家和行业的 id
数量。
计算示例:2017/01/03
上的 HHI 计算为 (3/5)^2 (industry A) + (1/5)^2 (industry B) + (1/5)^2 (industry C) = 0.44
,其中 分母 在相应日期等于 value_country
numerator 是每个行业的最新 value_country_industry
(即份额,但在 当前 日期。这意味着我不能只是工作与 share
列。)
扩展到更大数据(并可能使用 NA
s)的解决方案将是理想的(因此,data.table
标签)。
示例数据
library(data.table)
library(dplyr)
ID <- c("1","2","3","4","5","6")
Date <- c("2017-01-01","2017-01-02", "2017-01-02", "2017-01-02", "2017-01-03","2017-01-02")
Industry <- c("A","A","B","C","A","A")
Country <- c("UK","UK","UK","UK","UK","US")
Value_country<- c(1,4,4,4,5,1)
Value_country_industry<- c(1,2,1,1,3,1)
Share <- c(1,0.5,0.25,0.25,0.6,1)
Desired <- c(1,0.375,0.375,0.375,0.44,1)
dt <- data.frame(id=ID, date=Date, industry=Industry, country=Country, value_country=Value_country, value_country_industry=Value_country_industry, desired_output=Desired)
setDT(dt)[, date := as.Date(date)]
一种方法是将数据范围扩大,以便更容易说明“最近的”value_country_industry”规则。
然后填写并用 0 替换任何 NA。
然后可以跨列计算 HHI,确保无论有多少行业,它都能正常工作。
library(magrittr)
dt_wide <- dt[, -c('desired_output')] %>%
setnames(c('value_country', 'value_country_industry'), c('vc', 'vci')) %>%
dcast(country + date ~ industry, fun.aggregate = last, fill = NA,
value.var = c('vc', 'vci'))
vci_cols <- names(dt_wide) %>% .[grepl('vci', .)]
dt_wide[, (vci_cols) := lapply(.SD, nafill, type = 'locf'), by = 'country',
.SDcols = vci_cols] %>%
setnafill(fill = 0L, cols = 3:length(.))
dt_wide[, num := Reduce('+', .SD ^ 2), .SDcols = patterns('vci_')]
dt_wide[, den := Reduce('pmax', .SD ^ 2), .SDcols = patterns('vc_')]
dt_wide[, hhi := num / den]
dt_wide[, c('num', 'den') := NULL]
dt[dt_wide, hhi := hhi, on = c('country', 'date')]
dt
id date industry country value_country value_country_industry desired_output hhi
1: 1 2017-01-01 A UK 1 1 1.000 1.000
2: 2 2017-01-02 A UK 4 2 0.375 0.375
3: 3 2017-01-02 B UK 4 1 0.375 0.375
4: 4 2017-01-02 C UK 4 1 0.375 0.375
5: 5 2017-01-03 A UK 5 3 0.440 0.440
6: 6 2017-01-02 A US 1 1 1.000 1.000