Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 用分母除以变量前后的值之和_Loops_Sorting_Foreach_Stata - Fatal编程技术网

Loops 用分母除以变量前后的值之和

Loops 用分母除以变量前后的值之和,loops,sorting,foreach,stata,Loops,Sorting,Foreach,Stata,我想计算一个除法,分子是日内变量,分母是特定日期前后两天的值的总和。如下表所示,此新变量称为调整后的 * Example generated by -dataex-. To install: ssc install dataex clear input str1 name int date double time byte(Intraday daily) double adjusted "A" 19693 -1.8934218e+12 1 . . "A" 19693 -1.8

我想计算一个除法,分子是日内变量,分母是特定日期前后两天的值的总和。如下表所示,此新变量称为调整后的

* Example generated by -dataex-. To install: ssc install dataex
clear
input str1 name int date double time byte(Intraday daily) double adjusted
"A" 19693 -1.8934218e+12 1 .         .
"A" 19693   -1.89342e+12 2 3         .
"A" 19694 -1.8934182e+12 3 .         .
"A" 19694 -1.8934164e+12 2 5         .
"A" 19695   -1.89342e+12 2 .  .0952381
"A" 19695 -1.8934182e+12 1 . .04761905
"A" 19695 -1.8934164e+12 1 4 .04761905
"A" 19696 -1.8934146e+12 1 . .04347826
"A" 19696 -1.8934128e+12 3 . .13043478
"A" 19696  -1.893411e+12 3 7 .13043478
"A" 19699 -1.8934218e+12 1 .       .05
"A" 19699   -1.89342e+12 1 2       .05
"A" 19700 -1.8934182e+12 2 . .11111111
"A" 19700 -1.8934164e+12 3 5 .16666667
"A" 19709 -1.8934146e+12 1 . .07692308
"A" 19709 -1.8934128e+12 1 2 .07692308
"A" 19710  -1.893411e+12 2 2         .
"A" 19720 -1.8934218e+12 1 .         .
"A" 19720   -1.89342e+12 1 2         .
"B" 19700 -1.8934182e+12 2 .         .
"B" 19700 -1.8934146e+12 2 .         .
"B" 19700  -1.893411e+12 1 5         .
"B" 19706 -1.8934218e+12 1 .         .
"B" 19706 -1.8934182e+12 1 2         .
"B" 19707 -1.8934128e+12 2 . .13333333
"B" 19707  -1.893411e+12 1 3 .06666667
"B" 19716 -1.8934218e+12 1 1 .08333333
"B" 19717   -1.89342e+12 2 .      .125
"B" 19717 -1.8934182e+12 2 4      .125
"B" 19718 -1.8934128e+12 2 2      .125
"B" 19722 -1.8934218e+12 3 .         .
"B" 19722   -1.89342e+12 2 .         .
"B" 19722 -1.8934182e+12 1 6         .
"B" 19726 -1.8934164e+12 1 .         .
"B" 19726 -1.8934146e+12 1 .         .
"B" 19736 -1.8934128e+12 1 3         .
end
format %tdnn/dd/CCYY date
format %tcHH:MM:SS time
让我给你举个例子。
调整后的
列中日期
2013年12月3日
的值
0.0952381
(2/(3+5+4+7+2))
。值
2
作为分子是
2013年12月3日的
intraday
值,分母是该特定日期前后两天的
daily
值加上
daily
的总和。另一个例子是,2013年4月12日的
调整的
0.04347826
(1/(3+5+4+7+2))


如何在表1中创建变量
adjusted

有两种方法可以做到这一点(实际上,可能有无限的,但我将展示两种方法)。第一种方法是将数据压缩成一个每日汇总统计数据集,并在此基础上计算每天的分母。第二种方法是在
egen
的帮助下基本上做到这一点,而无需保留原始数据。我更喜欢方法1,因为它更明显,更清楚发生了什么,但每个人都有自己的想法

首先,读入数据并将其保存为临时文件。我还将对“name”变量进行
编码,以便我们可以使用时间序列运算符:

 * Example generated by -dataex-. To install: ssc install dataex
    clear
    input str1 name int date double time byte(Intraday daily) double adjusted
    "A" 19693 -1.8934218e+12 1 .         .
    "A" 19693   -1.89342e+12 2 3         .
    "A" 19694 -1.8934182e+12 3 .         .
    "A" 19694 -1.8934164e+12 2 5         .
    "A" 19695   -1.89342e+12 2 .  .0952381
    "A" 19695 -1.8934182e+12 1 . .04761905
    "A" 19695 -1.8934164e+12 1 4 .04761905
    "A" 19696 -1.8934146e+12 1 . .04347826
    "A" 19696 -1.8934128e+12 3 . .13043478
    "A" 19696  -1.893411e+12 3 7 .13043478
    "A" 19699 -1.8934218e+12 1 .       .05
    "A" 19699   -1.89342e+12 1 2       .05
    "A" 19700 -1.8934182e+12 2 . .11111111
    "A" 19700 -1.8934164e+12 3 5 .16666667
    "A" 19709 -1.8934146e+12 1 . .07692308
    "A" 19709 -1.8934128e+12 1 2 .07692308
    "A" 19710  -1.893411e+12 2 2         .
    "A" 19720 -1.8934218e+12 1 .         .
    "A" 19720   -1.89342e+12 1 2         .
    "B" 19700 -1.8934182e+12 2 .         .
    "B" 19700 -1.8934146e+12 2 .         .
    "B" 19700  -1.893411e+12 1 5         .
    "B" 19706 -1.8934218e+12 1 .         .
    "B" 19706 -1.8934182e+12 1 2         .
    "B" 19707 -1.8934128e+12 2 . .13333333
    "B" 19707  -1.893411e+12 1 3 .06666667
    "B" 19716 -1.8934218e+12 1 1 .08333333
    "B" 19717   -1.89342e+12 2 .      .125
    "B" 19717 -1.8934182e+12 2 4      .125
    "B" 19718 -1.8934128e+12 2 2      .125
    "B" 19722 -1.8934218e+12 3 .         .
    "B" 19722   -1.89342e+12 2 .         .
    "B" 19722 -1.8934182e+12 1 6         .
    "B" 19726 -1.8934164e+12 1 .         .
    "B" 19726 -1.8934146e+12 1 .         .
    "B" 19736 -1.8934128e+12 1 3         .
    end
    format %tdnn/dd/CCYY date
    format %tcHH:MM:SS time


//  Save a temp file
    tempfile master using
    encode name, gen(panel) // Need this for tsset later
    save `master'
接下来,方法1

*************************************
*   Method 1: Collapse and Merge    *
*************************************


//  Collapse into table of aggregate daily values by day
    collapse (sum) Intraday, by(date panel)

//  Declare data time-series data
    tsset panel date, daily delta(1 day)

//  Calculate aggregate daily values for two days before and after that name-date
    /*  As you will notice here, you do not consistently ACTUALLY have two 
        days before and after each name-date, so they are all missing. Maybe
        in your full data you do, so I have included the appropriate time-series
        operators here (lags [l] and leads [f]).            */
    bysort panel (date): gen denominator_tslags = l2.Intraday + l.Intraday + Intraday + F.Intraday + F2.Intraday

    /*  Alternatively, you could use the values for the days you HAVE before 
        and after, even if the day isn't actually right before. This seems
        to be what you did in your example, but you ignored December 30th for
        name "B".                                                       */
    bysort panel (date): gen denominator = Intraday[_n-2] + Intraday[_n-1] + Intraday + Intraday[_n+1] + Intraday[_n+2]

    rename Intraday daily_calc
    * Save tempfile
    save `using'

//  Merge Using data onto date
    use `master'
    merge m:1 panel date using `using', keepusing(daily_calc denominator)
        assert _merge == 3  // All dates should be merged, even if denominator is missing

//  Generate "adjusted" variable
    gen double adjusted_actual = Intraday / denominator

    * Drop unnecessary variables...
    keep name date time Intraday daily daily_calc adjusted adjusted_actual
        order name date time Intraday daily daily_calc adjusted adjusted_actual

    * Double check that, the adjusted variables are the same...
    gen same = round(adjusted,0.000001) == round(adjusted_actual,0.000001)
现在,对于方法2:

*****************************
*   Method 2: Same Dataset  *
*****************************

    use `master', clear
    tempvar n N
    bysort panel date: egen daily_calc = total(Intraday)

    * For this method, I want a date for ONLY the final time within a date
    bysort panel date: gen `n' = _n
    bysort panel date: gen `N' = _N
    gen ts_date = date if `n' == `N'

    tsset panel ts_date
    sort panel ts_date

    replace panel = . if missing(ts_date)

    * Using Lags

    bysort panel (ts_date): gen denominator_tslags = l2.daily_calc + l.daily_calc + daily_calc + F.daily_calc + F2.daily_calc if !missing(panel)

    * Using pre-post day values
    bysort panel (ts_date): gen denominator = daily_calc[_n-2] + daily_calc[_n-1] + daily_calc + daily_calc[_n+1] + daily_calc[_n+2] if !missing(panel)

/*  Now, the "denominator" values represents 1 value of this denominator every 
    day. We want to set this denominator for every time within the day...   */

    bysort name date (time): egen denominator_full = mean(denominator)

    * Now calculate the ratio...
    gen double adjusted_actual = Intraday / denominator_full

    * Drop unnecessary variables...
    keep name date time Intraday daily daily_calc adjusted adjusted_actual
        order name date time Intraday daily daily_calc adjusted adjusted_actual

    * Double check that, the adjusted variables are the same...
    gen same = round(adjusted,0.000001) == round(adjusted_actual,0.000001)

有两种方法可以做到这一点(实际上,可能有无限的,但我将展示两种)。第一种方法是将数据压缩成一个每日汇总统计数据集,并在此基础上计算每天的分母。第二种方法是在
egen
的帮助下基本上做到这一点,而无需保留原始数据。我更喜欢方法1,因为它更明显,更清楚发生了什么,但每个人都有自己的想法

首先,读入数据并将其保存为临时文件。我还将对“name”变量进行
编码,以便我们可以使用时间序列运算符:

 * Example generated by -dataex-. To install: ssc install dataex
    clear
    input str1 name int date double time byte(Intraday daily) double adjusted
    "A" 19693 -1.8934218e+12 1 .         .
    "A" 19693   -1.89342e+12 2 3         .
    "A" 19694 -1.8934182e+12 3 .         .
    "A" 19694 -1.8934164e+12 2 5         .
    "A" 19695   -1.89342e+12 2 .  .0952381
    "A" 19695 -1.8934182e+12 1 . .04761905
    "A" 19695 -1.8934164e+12 1 4 .04761905
    "A" 19696 -1.8934146e+12 1 . .04347826
    "A" 19696 -1.8934128e+12 3 . .13043478
    "A" 19696  -1.893411e+12 3 7 .13043478
    "A" 19699 -1.8934218e+12 1 .       .05
    "A" 19699   -1.89342e+12 1 2       .05
    "A" 19700 -1.8934182e+12 2 . .11111111
    "A" 19700 -1.8934164e+12 3 5 .16666667
    "A" 19709 -1.8934146e+12 1 . .07692308
    "A" 19709 -1.8934128e+12 1 2 .07692308
    "A" 19710  -1.893411e+12 2 2         .
    "A" 19720 -1.8934218e+12 1 .         .
    "A" 19720   -1.89342e+12 1 2         .
    "B" 19700 -1.8934182e+12 2 .         .
    "B" 19700 -1.8934146e+12 2 .         .
    "B" 19700  -1.893411e+12 1 5         .
    "B" 19706 -1.8934218e+12 1 .         .
    "B" 19706 -1.8934182e+12 1 2         .
    "B" 19707 -1.8934128e+12 2 . .13333333
    "B" 19707  -1.893411e+12 1 3 .06666667
    "B" 19716 -1.8934218e+12 1 1 .08333333
    "B" 19717   -1.89342e+12 2 .      .125
    "B" 19717 -1.8934182e+12 2 4      .125
    "B" 19718 -1.8934128e+12 2 2      .125
    "B" 19722 -1.8934218e+12 3 .         .
    "B" 19722   -1.89342e+12 2 .         .
    "B" 19722 -1.8934182e+12 1 6         .
    "B" 19726 -1.8934164e+12 1 .         .
    "B" 19726 -1.8934146e+12 1 .         .
    "B" 19736 -1.8934128e+12 1 3         .
    end
    format %tdnn/dd/CCYY date
    format %tcHH:MM:SS time


//  Save a temp file
    tempfile master using
    encode name, gen(panel) // Need this for tsset later
    save `master'
接下来,方法1

*************************************
*   Method 1: Collapse and Merge    *
*************************************


//  Collapse into table of aggregate daily values by day
    collapse (sum) Intraday, by(date panel)

//  Declare data time-series data
    tsset panel date, daily delta(1 day)

//  Calculate aggregate daily values for two days before and after that name-date
    /*  As you will notice here, you do not consistently ACTUALLY have two 
        days before and after each name-date, so they are all missing. Maybe
        in your full data you do, so I have included the appropriate time-series
        operators here (lags [l] and leads [f]).            */
    bysort panel (date): gen denominator_tslags = l2.Intraday + l.Intraday + Intraday + F.Intraday + F2.Intraday

    /*  Alternatively, you could use the values for the days you HAVE before 
        and after, even if the day isn't actually right before. This seems
        to be what you did in your example, but you ignored December 30th for
        name "B".                                                       */
    bysort panel (date): gen denominator = Intraday[_n-2] + Intraday[_n-1] + Intraday + Intraday[_n+1] + Intraday[_n+2]

    rename Intraday daily_calc
    * Save tempfile
    save `using'

//  Merge Using data onto date
    use `master'
    merge m:1 panel date using `using', keepusing(daily_calc denominator)
        assert _merge == 3  // All dates should be merged, even if denominator is missing

//  Generate "adjusted" variable
    gen double adjusted_actual = Intraday / denominator

    * Drop unnecessary variables...
    keep name date time Intraday daily daily_calc adjusted adjusted_actual
        order name date time Intraday daily daily_calc adjusted adjusted_actual

    * Double check that, the adjusted variables are the same...
    gen same = round(adjusted,0.000001) == round(adjusted_actual,0.000001)
现在,对于方法2:

*****************************
*   Method 2: Same Dataset  *
*****************************

    use `master', clear
    tempvar n N
    bysort panel date: egen daily_calc = total(Intraday)

    * For this method, I want a date for ONLY the final time within a date
    bysort panel date: gen `n' = _n
    bysort panel date: gen `N' = _N
    gen ts_date = date if `n' == `N'

    tsset panel ts_date
    sort panel ts_date

    replace panel = . if missing(ts_date)

    * Using Lags

    bysort panel (ts_date): gen denominator_tslags = l2.daily_calc + l.daily_calc + daily_calc + F.daily_calc + F2.daily_calc if !missing(panel)

    * Using pre-post day values
    bysort panel (ts_date): gen denominator = daily_calc[_n-2] + daily_calc[_n-1] + daily_calc + daily_calc[_n+1] + daily_calc[_n+2] if !missing(panel)

/*  Now, the "denominator" values represents 1 value of this denominator every 
    day. We want to set this denominator for every time within the day...   */

    bysort name date (time): egen denominator_full = mean(denominator)

    * Now calculate the ratio...
    gen double adjusted_actual = Intraday / denominator_full

    * Drop unnecessary variables...
    keep name date time Intraday daily daily_calc adjusted adjusted_actual
        order name date time Intraday daily daily_calc adjusted adjusted_actual

    * Double check that, the adjusted variables are the same...
    gen same = round(adjusted,0.000001) == round(adjusted_actual,0.000001)

请注意,您的时间定义不明确

. di %tc -1.8934218e+12
31dec1899 09:30:00
这在这里不管用。在费尽周折才得出定义的情况下——您使用定义的值计算天数,而不是天数本身——我得到了以下代码(使用SSC提供的
rangestat
):


请注意,您的时间定义不明确

. di %tc -1.8934218e+12
31dec1899 09:30:00
这在这里不管用。在费尽周折才得出定义的情况下——您使用定义的值计算天数,而不是天数本身——我得到了以下代码(使用SSC提供的
rangestat
):


这是非常不清楚的。
name
扮演什么角色?为什么许多日期都有重复?为什么对于某些
名称、日期
组合,例如
19695
,会有不同的
日内
值?我使用的是一个高频数据集,即日内数据<代码>名称
是股票名称的变量。对于每个名称和日期重复此过程。请考虑,每个<代码>日期<代码>都有一些时间值。代码>日内
是每个
名称
日期
时间
的价格<代码>每日
是每个
名称
日期
日内
总和。感谢澄清。我的错误是没有足够仔细地查看
时间的值。这是非常不清楚的。
name
扮演什么角色?为什么许多日期都有重复?为什么对于某些
名称、日期
组合,例如
19695
,会有不同的
日内
值?我使用的是一个高频数据集,即日内数据<代码>名称
是股票名称的变量。对于每个名称和日期重复此过程。请考虑,每个<代码>日期<代码>都有一些时间值。代码>日内
是每个
名称
日期
时间
的价格<代码>每日
是每个
名称
日期
日内
总和。感谢澄清。我的错误是没有仔细查看
时间的值
。这里有很多很好的通用技术
rangestat
允许一些缩短。这里有很多很好的通用技术
rangestat
允许一些缩短。您的代码非常完美。我只是将代码的最后一行更改为以下语句:
gen wanted=Intraday/daily\u sum if daily\u count==5
您的代码是完美的。我只是将代码的最后一行更改为以下语句:
gen-wanted=Intraday/daily\u sum,如果daily\u count==5