0

I have a SPSS ctables statement that looks somewhat like this

CTABLES
  /TABLE (foo + bar) [C][ROWPCT.VALIDN PCT40.1, TOTALS[VALIDN F40.0, MISSING, TOTALN F40.0]]
  /CLABELS ROWLABELS=OPPOSITE
  /CATEGORIES VARIABLES=foo bar
    ORDER=A KEY=VALUE EMPTY=INCLUDE TOTAL=YES POSITION=AFTER MISSING=INCLUDE.

foo and bar are likert-scaled variables with identical categories.

I got ctables to include the number of system missings. What I need though is the percentage of system missings (or maybe the percentage of system and user missings) with respect to the total number of cases. Is there a way to achieve this by means of SPSS syntax (PCOMPUTE maybe?) or via python?

Regards

lith
  • 929
  • 8
  • 23

1 Answers1

1

I could not find a way to do this with CTABLES syntax, including PCOMPUTE, but a colleague did provide a Python solution. If you have the Python Essentials installed (which are installed by default on recent versions), copy and paste the following code into a syntax window, and after running CTABLES, run it.

preserve.
set printback none.
begin program python3.
import SpssClient
SpssClient.StartClient()
OutputDoc = SpssClient.GetDesignatedOutputDoc()
OutputItems = OutputDoc.GetOutputItems()
for index in range(OutputItems.Size()):
    OutputItem = OutputItems.GetItemAt(index)
    if OutputItem.GetType() == SpssClient.OutputItemType.PIVOT:
      PivotTable = OutputItem.GetSpecificType()
      ColLabels = PivotTable.ColumnLabelArray()
      for i in range(0,ColLabels.GetNumRows()):
        for j in range(ColLabels.GetNumColumns()):
          try:
            colText=ColLabels.GetValueAt(i,j)
            if colText == "Missing":
              MissingColumn=j
            if colText == "Valid N":
              ValidNColumn=j
            if colText == "Total N":
              TotalNColumn=j
          except:
            pass

      DataCells = PivotTable.DataCellArray()
      for i in range(DataCells.GetNumRows()):
        MissingVal=(DataCells.GetValueAt(i,MissingColumn))
        ValidN=(DataCells.GetValueAt(i,ValidNColumn))
        TotalN=(DataCells.GetValueAt(i,TotalNColumn))
        val= str( 100 * float(MissingVal)/float(TotalN) )
        DataCells.SetValueAt(i,MissingColumn,val)
        DataCells.SetNumericFormatAtWithDecimal(i,MissingColumn,"##.#%",1)

SpssClient.StopClient()
end program.
restore.

Here's what the result looks like with a small example dataset:

CTABLES with modification

David Nichols
  • 576
  • 3
  • 5
  • Great! Thanks a lot. I had to make a minor trivial adjustment in order to make it work with my installation of spss. In some cases, the *Column variables weren't set and caused an error, which is why I reset these variables to None at the beginning of the first for loop and then checked in front of the second block whether they are set to a number. – lith Jun 03 '20 at 11:08