【问题标题】:Using a loop to replace values of a variable使用循环替换变量的值
【发布时间】:2017-05-06 07:46:02
【问题描述】:

我正在尝试在我的数据集中创建一个新变量来存储一个数字,该数字是从同一观察中对另一个数字的计算得出的。

* Here is what my dataset looks like:
SubjectID    Score     MyNewScore
1001         5442822   0
1002         6406134   0
1003         16        0

现在,变量 Score 是最多 23 个不同数字的总和(我将它们称为“响应”),范围从 1 到 8,388,608。

/* Example of response values
1st response = 1
2nd response = 2
3rd response = 4
4th response = 8
5th response = 16
6th response = 32
...
23rd response = 8,388,608
*/

MyNewScore 包含这些不同响应的计数,这些响应用于获取Score 中的值。在我的示例数据集中,MyNewScore 应该等于 9,因为有 9 个响应用于达到 5,442,822 的总和。

我在Stata中的while循环中嵌套了一个forvalues循环,该循环成功计算了MyNewScore,但我不知道如何用我的嵌套循环的结果替换数据集中当前存在的0。

用于计算我所追求的值的Stata代码:

// Build a loop to create a Roland Morris Score
local score = 16
local count = 0

while `score' != 0 {

    local ItemCode
        forvalues i=1/24
            local j = 2^(`i' - 1)
            if `j' >= `score' continue, break
            local ItemCode `j'
        *   display "`ItemCode'"
        }

    local score = `score' - `ItemCode'
    if `score' > 1 {
        local count = `count' + 1
        display "`count'"
    }
    else if `score' == 1 {
        local count = `count' + 1
        display "`count'"
        continue, break
    }
}

我如何 replace MyNewScore 中的 0 与嵌套循环的输出?我尝试使用“替换”命令将这两个循环嵌套在另一个while 循环中,尽管这只是将第一次观察的计数应用于数据集中的所有观察。

【问题讨论】:

    标签: stata


    【解决方案1】:

    我认为第 23 次响应的值有错误,应该是2^(23-1),即 4,194,304。

    前 4 个响应的总和是 15;那是1+2+4+82^4-1。所有 23 个响应的总和为 2^23 - 1,因此 Score 的最大可能值为 8,388,607。

    这里不需要循环观察。您从 Score 变量的克隆副本开始。您遍历每个响应,从最高到 1。在每次通过时,如果当前分数高于或等于响应的值,则计算该响应并从分数中减去该值。

    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input long(SubjectID Score)
    1001 5442822
    1002 6406134
    1003      16
    1004       1
    1005      19
    1006      15
    1007 8388607
    end
    
    clonevar x = Score
    gen wanted = 0
    qui forvalues i=23(-1)1 {
        local response = 2^(`i'-1)
        replace wanted = wanted + 1 if x >= `response'
        replace x = x - `response' if x >= `response'
    }
    

    【讨论】:

    • 感谢您的回复!尽管这是我的错字,但您对错误的看法是正确的。实际上有 24 个回复,所以我应该输入 2^(24-1)。我已经尝试过您的解决方案,但在 forvalues 行上出现“类型不匹配”错误。另外,您能解释一下(-1)1 语法的作用吗?
    • “类型不匹配”错误已更正。原来该列是字符数据,因为缺少值。我通过使用destring wanted, replace force 进行了更正,然后应用了您的解决方案。它工作得很好!谢谢!
    【解决方案2】:

    我认为您需要做的就是将代码嵌套在一个循环中,该循环遍历数据集中的每个变量,如下所示:

    // get total number of observations in dataset
    local N = _N 
    
    // go through each observation and run the while loop
    forvalues observation = 1/`N' {
        local score = Score[`observation']
        local count = 0
    
        // your while loop here
        while `score' != 0 {
            ...
        }
    
        replace MyNewScore = `ItemCode' in `observation' // (or whatever value you're after)
    }
    

    这就是你所追求的吗?

    【讨论】:

    • 我会尽快试用并通知您。谢谢!
    • 我收到“无效语法”错误。我将继续检查我的代码,看看是否能找到错误。我可能需要在星期一用修改后的代码更新我的帖子。谢谢到目前为止你的帮助!
    • 我的错误,我在上面的代码中犯了一个错误,我现在已经修复了
    • 不幸的是,“无效语法”错误仍然存​​在。我确定您的代码没问题,并且错误在于我编写的内容。
    猜你喜欢
    • 2015-03-22
    • 1970-01-01
    • 2021-08-01
    • 2012-08-28
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 2016-06-05
    相关资源
    最近更新 更多