Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • stset program glitching

    I am trying to write a wrapper placed in a do file to include for survival analysis. There is date of diagnosis (dodx), date of transplant (dotsp1), docensor (censor date). I want to generate three different analysis time options and call each as relevant. I am using version 19.0.
    I am unable to see why the syntax is not correct, even from the trace. Happy to share a dataex if that would help.

    Code:
    cap program drop stset_custom
    program define stset_custom
        // note: no [ ] around the options here
        syntax , mode(string) [months(real)]
    
        // 1. Determine default months if not supplied
        if ("`months'" == "") {
            if "`mode'" == "dx_cens"       local months 24
            else if "`mode'" == "tx_cens" local months 60
            else if "`mode'" == "dx_txcens" local months 24
            else {
                di as error "Unknown mode `mode'.  Allowed: dx_cens, tx_cens, dx_txcens"
                exit 198
            }
        }
    
        // 2. Echo the program statements
        di as txt "// stset_custom: mode=`mode', censor at `months' months"
    
        // 3. Dispatch to the right stset call
        if "`mode'" == "dx_cens" {
            stset docens, fail(dead)                               ///
                 origin(time dodx) enter(time dodx)               ///
                 exit(time dodx + `months' * 30.455)             ///
                 scale(30.455) id(obs)
        }
        else if "`mode'" == "tx_cens" {
            stset docens, fail(dead)                               ///
                 origin(time dotsp1) enter(time dotsp1)           ///
                 exit(time dotsp1 + `months' * 30.455)            ///
                 scale(30.455) id(obs)
        }
        else if "`mode'" == "dx_txcens" {
            tempvar exit_time
            gen double `exit_time' = min(dotsp1, dodx + `months' * 30.455)
            format `exit_time' %td
            stset docens, fail(dead)                               ///
                 origin(time dodx) enter(time dodx)               ///
                 exit(time `exit_time')                           ///
                 scale(30.455) id(obs)
            drop `exit_time'
        }
    end
    Result with trace on:

    Code:
    set trace on
    st_set, mode(dx_cens) months(24)
    
    
    . st_set, mode("dx_cens") months(24)
      ------------------------------------------------------------- begin st_set ---
      - version 6, missing
      - if ("`1'"=="clear") {
      = if (","=="clear") {
        Clear
        exit
        }
      - if ("`1'" != "set") { exit 198 }
      = if ("," != "set") { exit 198 }
      --------------------------------------------------------------- end st_set ---
    r(198);

    The program sits inside a utils.do file (as invoked below) that I -qui do- as below and not in an ado file:
    Code:
    *--------------------PROJECT INITIALIZATION SCRIPT-----------------------------*
                            local prfolder prj_sv
                include DIRECTORY_INITIALIZATION_sv.DOH, adopath
    *----------------------------Chunker-------------------------------------------*
    
    *************************************************************************
    *Impact of Tazy score within TP53 mutated high-grade myeloid neoplasm
    *************************************************************************
    // Program: p53_descr_docs.do
    // Task   : Uses an01-merged.dta and the long file with all TP53 mutations per case.
    // Outputs: Descriptive writeup for the paper
    // Project: TP53 mutations in myeloid and outcome
    // Author : GV \date: 2023-11-02 
    di "`c(current_date)'"
    
    // ====================================================================
    **#                  Data subsetting for study
    // ====================================================================
    use "`prfold'/dtafiles//an01-merged.dta"
    * Check totals
        isid mrn
    
        // Change dir to includes folder
    *-------------------------------
    cd "`pwork'"
    qui include unicoder 
    qui do utils
    
    // Include data subsetting, ST setting for OS24
    *----------------------------------------------      
    qui include"`prdo'/selects//p53select.doh"
    
    
    
    // Include all figure call and style macros
    *------------------------------------------
    qui include "`prdo'/selects//includefig.doh"  
    qui include "`prdo'/selects//pdocstyles.doh"    // Figure calls

  • #2
    The command -st_set, mode("dx_cens") months(24)- is incompatible with the code that initiates program st_set. That code begins with reference to local macro 1. When you issue a command to Stata, the parser defines local macro 0 to include the entire command. Local macro 1 is then set to be the first token following the command name. In your command, that token would be just a comma. So `"`1'"' expands to `","'. The code checks to say if that equals `"clear"', which evidently it does not. So the Clear command is skipped, and execution proceeds to check if `"`1'"' == `"set"', which, equally evidently, it does not. So the -exit 198- command is executed. -st_set- expects that the first thing immediately following is going to be either "clear" or "set," but the command you show lists nothing there. That is the source of the error you are seeing.

    Now, it appears that the call to -st_set- is deep inside some nested do files and maybe inside an ado as well. So it isn't clear to me whether you wrote that command or just inherited it. But whatever may be the case, either that line of code must be changed, or program -st_set- must be recoded to allow for a call with nothing specified between st_set and the comma that sets off the options.

    Comment


    • #3
      Thanks for the explanation, Clyde Schechter. You surmised right that this is indeed a wrapper I did not write on my own. Sorry I tried LLM to wrap it for me and it sure failed. I tried changing the syntax to
      Code:
      syntax, mode(string asis) months(real)
      And the wrapper worked. Although I am not understanding how it seems to work. I can see my Stata skills regressing quickly ever since I started dabbling in LLM.

      Below is a little top portion of -set trace- for someone else who wants to see more for diagnosis to censor at 60 months post diagnosis.

      Code:
      . set trace on
      
      . stset_custom, mode(dx_cens) months(60)
        ------------------------------------------------------- begin stset_custom ---
        - version 19
        - syntax, mode(string asis) months(real)
        - if "`months'" == "" {
        = if "60" == "" {
          if "`mode'" == "dx_cens" local months 24
          else if "`mode'" == "tx_cens" local months 60
          else if "`mode'" == "dx_txcens" local months 24
          else {
          di as err "Unknown mode `mode'.  Allowed: dx_cens tx_cens dx_txcens"
          exit 198
          }
          }
        - di as txt "// stset_custom: mode=`mode', censor=`months' mo"
        = di as txt "// stset_custom: mode=dx_cens, censor=60 mo"
      // stset_custom: mode=dx_cens, censor=60 mo
        - if "`mode'" == "dx_cens" {
        = if "dx_cens" == "dx_cens" {
        - stset docens, fail(dead) origin(time dodx) enter(time dodx) exit(time dodx +
      >  `months'*30.455) scale(30.455) id(obs)
        = stset docens, fail(dead) origin(time dodx) enter(time dodx) exit(time dodx +
      >  60*30.455) scale(30.455) id(obs)
          ------------------------------------------------------------ begin stset ---

      Comment


      • #4
        Although I am not understanding how it seems to work.
        It works because it no longer relies on the values of `0', `1', ... The -syntax- command you correctly used requires nothing at all following the command name itself before the comma and options. And it correctly parses the options and passes them into local macros mode and months, which are then used in the code in the way you require.

        Comment


        • #5
          As I understand it, the local macro 1 could also legally be (meaning, contain) a comma followed immediately by any option call legal according to syntax. So that is further reason why looking at element 1 is not a good idea.

          For example

          Code:
          ,clear 
          could be the first token, as explained by Clyde Schechter It's just custom not the law for many users to follow a comma with a space in this context, or indeed to precede the comma with a space.

          For example

          Code:
          d,s
          d , s
          d ,s
          are all equivalent to Stata.

          Comment


          • #6
            Thanks both, Clyde Schechter and Nick Cox. Both your comments definitely helped me understand the logic of the syntax line.

            Comment

            Working...
            X