Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to save a value of 0 for FORMAT_TYPE_F variables. It gets written as a blank value every time. No luck using the values array. #53

Open
ghost opened this issue Feb 7, 2020 · 1 comment

Comments

@ghost
Copy link

ghost commented Feb 7, 2020

I can't get the library to export actual zero values for variables with the format Variable::FORMAT_TYPE_F. Instead, the library is converting all 0 values to blanks when writing the SPSS file. Here is some sample code that will illustrate the point.

$file = '<path>'
$data = [
    'header' => [
        'creationDate' => '01 01 2020',
        'creationTime' => '01:01:01',
    ],
    'variables' => [
        [
            'name'       => 'TEST_VAR',
            'format'     => Variable::FORMAT_TYPE_F,
            'width'      => 40,
            'decimals'   => 2,
            'label'      => 'TEST LABEL',
            'values'     => [],
            'columns'    => 5,
            'alignment'  => Variable::ALIGN_RIGHT,
            'measure'    => Variable::MEASURE_SCALE,
            'attributes' => [
                '$@Role' => Variable::ROLE_INPUT,
            ],
            'data'       => [1,0,2,3,4,0,5],
        ]
    ],
];

$writer = new Writer($data);
$writer->save($file);

If I write this to a file the responses with '0' as the value will be blank, not the number 0. I've tried adding the following:

'values' => ['0' => '0'],

and

'values' => ['0.00' => '0'],

I've tried other variations with and with out quotes and some end up creating a corrupt SPSS file and the others didn't work as well. I've also tried making sure the zeroes in the data array are entered as 0.00 but that did not work either.

I'm imagine I must be missing something but this appears to be a bug. Thanks in advance for your time!

@tiamo tiamo closed this as completed in ec2682d Dec 16, 2020
@tiamo tiamo reopened this Dec 16, 2020
SamMousa pushed a commit to collecthor/spss that referenced this issue Mar 18, 2021
For numeric values, we only need to increment $nominalIdx by 1. With date having width of 20, Utils::widthToOcts($var->width) returns 3 and $nominalIndex is no longer correctly calculated as it shifts subsequent variables too far.
@lestcape
Copy link
Collaborator

@davechez I think that is what is expected to happen, let me explain.

I added an info section to your example for a better explanation in the data variable in this way:

$file = '<path>';
$data = [
    'header' => [
        'creationDate' => '01 01 2020',
        'creationTime' => '01:01:01',
    ],
    'info' => [
        'machineFloatingPoint' => [
            'sysmis' => -1.7976931348623157e+308,
            'highest' => 1.7976931348623157e+308,
            'lowest' => -1.7976931348623155e+308,
        ],
    ],
    'variables' => [
        [
            'name'       => 'TEST_VAR',
            'format'     => Variable::FORMAT_TYPE_F,
            'width'      => 40,
            'decimals'   => 2,
            'label'      => 'TEST LABEL',
            'values'     => [],
            'columns'    => 5,
            'alignment'  => Variable::ALIGN_RIGHT,
            'measure'    => Variable::MEASURE_SCALE,
            'attributes' => [
                '$@Role' => Variable::ROLE_INPUT,
            ],
            'data'       => [1,0,2,3,4,0,5],
        ]
    ],
];

$writer = new Writer($data);
$writer->save($file);

As you can see I set a sysmis value and if i don't set it, it will be 0 as your own example case. The sysmis tell to the sav file what is the numeric value that should be interpreted as a missing value. So, as you don't set any value 0 is assumed as the system missing value and that is why you get it always as a blank value every time.

In my example, I set a sysmis different to 0, so now i can set 0 and and read it as 0 instead of blank. If in my example I need to set a missing value, i have two options. I need to use the sysmis that i defined or i can set an empty string ''. So if i need a missing value in the first position i can do:

 'data'       => ['',0,2,3,4,0,5],

This is possible because of this condition, but probably will be good to add also a check for a php null value to that line. Something like:

} elseif ($value === $sysmis || '' === $value || !isset($value)) {

and then this can help us to defined the data in a more common way as:

 'data'       => [null,0,2,3,4,0,5],

It's also important to mention that when you are reading you sav file you also need to read the sysmis value that is set in the file header:

public function getSystemMissingValue() {
    $subType = SPSS\Sav\Record\Info\MachineFloatingPoint::SUBTYPE;
    if (isset($this->savReader) && isset($this->savReader->info) && isset($this->savReader->info[$subType])) {
        return $this->savReader->info[$subType]->sysmis;
    }
    return null;
}

and then check what value is a missing value in your data, otherwise the missing values will appeared as the value of the sysmis and probably this is not what you want to occurs in your app. I hope this will help you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants