Announcement

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

  • Grouped forestplot without subgroup meta-analysis

    I have data on costs of different patient groups over several months and want to use a forestplot to graph them, along with text of the cost differences and confidence intervals. I'm not doing a meta-analysis, so I don't want or need any summaries by subgroup.
    I attempted to do this with the Stata package meta (Stata/SE 19.0) and can get very close, but can't figure out how to turn off the subgroup summary. I can delete those rows one-by-one with the gr_edit command, but I can't figure out how to get rid of the extra vertical space where they were sitting (see code and graph below).

    I thought about using the user command coefplot by Ben Jann, but I want to graph the cost differences and CI as shown.

    QUESTIONS:
    Is there a way to remove that extra space between the Disease A and Disease B panels?
    Or is there another approach I should try?


    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input str13 disease byte month double(expdiff lowerci upperci pvalue)
    "A"  1   3468.908935546875    2975.86865234375   3961.949462890625                      0
    "A"  6   348.3434753417969   94.27411651611328    602.412841796875    .007204913999885321
    "A" 12  -167.5044403076172   -392.356201171875  57.347320556640625       .144266739487648
    "B"  1   3848.995361328125   3749.573974609375     3948.4169921875                      0
    "B"  6   290.9801940917969  248.13168334960938   333.8287353515625                      0
    "B" 12 -295.72747802734375  -332.2401428222656       -259.21484375                      0
    end
    
    
    
     meta set expdiff lowerci upperci, civartolerance(1e-2) studylabel(month) eslabel(Cost difference)
     meta forestplot _id _plot _esci if inlist(month, 1, 6, 12), subgroup(disease) columnopts(_id,    title(Disease)) ///
    columnopts(_es, format(%6.0fc)) noomarker nowmarkers nogmarkers nullrefline(favorsright(Higher costs for disease population)) ///
    noohetstats noohomtest noosigtest noghetstats nogsigtests nogwhomtests nogbhomtests nooverall markeropts(msize(large) msymbol(o)) ///
    nonotes xlabel(-500 0 1000 2000 3000 4000 5000, labsize(small))
    
    
    gr_edit .plotregion1.column5.group_items[1].Delete
    gr_edit .plotregion1.column5.group_items[2].Delete
    gr_edit .plotregion1.column5.group_items[3].Delete
    gr_edit .plotregion1.column6.group_items[1].Delete
    gr_edit .plotregion1.column6.group_items[2].Delete
    gr_edit .plotregion1.column6.group_items[3].Delete
    gr_edit .plotregion1.column7.group_items[1].Delete
    gr_edit .plotregion1.column7.group_items[2].Delete
    gr_edit .plotregion1.column7.group_items[3].Delete
    gr_edit .set_spositions
    gr_edit .set_graphwidth


    Attached Files
    Last edited by Molly Jeffery; 01 Apr 2026, 09:21. Reason: Removing duplicate images

  • #2
    In your setup, you are simply hiding the subgroup-level confidence intervals (CIs), which explains the extra space. I am not aware of a way to suppress the values of the subgroup-level CIs when using the subgroup() option, and there is limited flexibility without subgroups. If you do not mind not having spaces between subgroups, you can instead modify the study labels by placing the subgroup labels in front of the first item in each group and indenting the text of the individual items within each subgroup.

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input str13 disease byte month double(expdiff lowerci upperci pvalue)
    "A"  1   3468.908935546875    2975.86865234375   3961.949462890625                      0
    "A"  6   348.3434753417969   94.27411651611328    602.412841796875    .007204913999885321
    "A" 12  -167.5044403076172   -392.356201171875  57.347320556640625       .144266739487648
    "B"  1   3848.995361328125   3749.573974609375     3948.4169921875                      0
    "B"  6   290.9801940917969  248.13168334960938   333.8287353515625                      0
    "B" 12 -295.72747802734375  -332.2401428222656       -259.21484375                      0
    end
    
    gen strmonth= string(month)
    replace strmonth= "{bf:Group }" + "{bf:"+disease+"}     "   +strmonth if month==1
    replace strmonth= "`=uchar(28)'" + "                   "  + "`=uchar(28)'"  +strmonth if  month!=1
    
    meta set expdiff lowerci upperci, civartolerance(1e-2) studylabel(strmonth) eslabel(Cost difference)
    
    meta forestplot _id _plot _esci if inlist(month, 1, 6, 12), ///
    columnopts(_id, title(Disease))  columnopts(_es, format(%6.0fc)) ///
    noomarker nowmarkers nogmarkers ///
    nullrefline(favorsright(Higher costs for disease population)) ///
    noohetstats noohomtest noosigtest noghetstats nogsigtests nogwhomtests ///
     nogbhomtests nooverall markeropts(msize(large) msymbol(o)) ///
    nonotes xlabel(-500 0 1000 2000 3000 4000 5000, labsize(small))
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	49.0 KB
ID:	1785552

    Comment


    • #3
      Here is a way to use coefplot from SSC with your data (with groups expanded/ duplicated). You will need to manually set the x-value in the margin where you want the coefficient and confidence interval values to be displayed (highlighted below).

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input str13 disease byte month double(expdiff lowerci upperci pvalue)
      "A"  1   3468.908935546875    2975.86865234375   3961.949462890625                      0
      "A"  6   348.3434753417969   94.27411651611328    602.412841796875    .007204913999885321
      "A" 12  -167.5044403076172   -392.356201171875  57.347320556640625       .144266739487648
      "B"  1   3848.995361328125   3749.573974609375     3948.4169921875                      0
      "B"  6   290.9801940917969  248.13168334960938   333.8287353515625                      0
      "B" 12 -295.72747802734375  -332.2401428222656       -259.21484375                      0
      "C"  1   3468.908935546875    2975.86865234375   3961.949462890625                      0
      "C"  6   348.3434753417969   94.27411651611328    602.412841796875    .007204913999885321
      "C" 12  -167.5044403076172   -392.356201171875  57.347320556640625       .144266739487648
      "D"  1   3848.995361328125   3749.573974609375     3948.4169921875                      0
      "D"  6   290.9801940917969  248.13168334960938   333.8287353515625                      0
      "D" 12 -295.72747802734375  -332.2401428222656       -259.21484375                      0
      end
      
      gen strmonth= string(month)
      mkmat expdiff-upperci, mat(res) rownames(strmonth) roweq(disease)
      mat res = res'
      
      gen at= _n + sum(disease!=disease[_n-1]) -1 if disease!=disease[_n-1] 
      replace at = at[_n-1]+1 if missing(at) & !missing(at[_n-1]) 
      gen xpos = 4500
      gen label = `" " "' +string(expdiff,"%5.0f")+" ["+ string(lowerci,"%5.2f") + ", " + string(upperci,"%5.2f") + "]" + `" " "'
      replace label = "text(" + string(at) + " " + string(xpos) + " " + label  + ", place(e) size(small))" 
      levelsof label, local(labels) clean
      
      coefplot  mat(res), ci((2 3)) keep(*:) `labels' graphr(margin(r=50))
      Click image for larger version

Name:	Graph.png
Views:	1
Size:	37.1 KB
ID:	1785559

      Comment


      • #4
        These are both fantastic solutions--thank you so much, Andrew! I really appreciate the time you put into thoughtful solutions!

        Comment

        Working...
        X