Spss variable, value and reader wrapper.
authorTomas Zeman <tzeman@volny.cz>
Thu, 14 Mar 2019 15:06:13 +0100
changeset 2 7461111ce9ed
parent 1 3a70d40db0fd
child 3 a6bf3dddbb7c
Spss variable, value and reader wrapper.
jvm/src/net/tz/spss/SpssReader.scala
shared/net/tz/spss/SpssValue.scala
shared/net/tz/spss/SpssVariable.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvm/src/net/tz/spss/SpssReader.scala	Thu Mar 14 15:06:13 2019 +0100
@@ -0,0 +1,25 @@
+package net.tz.spss
+
+import java.io.File
+
+import com.bedatadriven.spss.SpssDataFileReader
+
+import scala.collection.JavaConverters._
+import scala.language.postfixOps
+
+class SpssReader(private val r: SpssDataFileReader)
+  extends Iterator[Map[SpssVariable, SpssValue]] {
+
+  lazy val variables: List[SpssVariable] =
+    r.getVariables.asScala.toList map(SpssVariable(_))
+
+  override def hasNext: Boolean = r.readNextCase()
+
+  override def next(): Map[SpssVariable, SpssValue] =
+    variables map(v => (v, SpssValue(r, v))) toMap
+
+}
+
+object SpssReader {
+  def apply(f: File): SpssReader = new SpssReader(new SpssDataFileReader(f))
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shared/net/tz/spss/SpssValue.scala	Thu Mar 14 15:06:13 2019 +0100
@@ -0,0 +1,33 @@
+package net.tz.spss
+
+import com.bedatadriven.spss.SpssDataFileReader
+
+sealed trait SpssValue
+
+sealed trait Missing extends SpssValue
+
+abstract class Value[T] extends SpssValue {
+  def v: T
+}
+
+abstract class MissingValue[T] extends Value[T]
+
+case class StringValue(v: String) extends Value[String]
+case class DoubleValue(v: Double) extends Value[Double]
+case object SystemMissing extends Missing
+// ??? case class MissingString(v: String) extends MissingValue[String]
+case class MissingDouble(v: Double) extends MissingValue[Double]
+
+object SpssValue {
+
+  def apply(r: SpssDataFileReader, variable: SpssVariable): SpssValue = {
+    val i = variable.index
+    if (r.isSystemMissing(i))
+      SystemMissing
+    else
+      Option(r.getDoubleValue(i)) map(x =>
+        if (r.isValueMissing(i, x)) MissingDouble(x) else DoubleValue(x)
+        ) orElse (Option(r.getStringValue(i)) map StringValue
+        ) getOrElse SystemMissing
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shared/net/tz/spss/SpssVariable.scala	Thu Mar 14 15:06:13 2019 +0100
@@ -0,0 +1,32 @@
+package net.tz.spss
+
+import net.tz.spss.SpssVariable.DoubleRange
+import com.bedatadriven.spss.{SpssVariable => JVar}
+
+import scala.collection.JavaConverters._
+import scala.language.postfixOps
+
+case class SpssVariable(name: String, shortName: String, isNumeric: Boolean,
+  index: Int, label: String,
+  missingRange: Option[DoubleRange] = None,
+  missing: List[Double] = Nil,
+  missingStrings: List[String] = Nil,
+  labels: Map[Double, String] = Map())
+
+object SpssVariable {
+  type DoubleRange = (Double, Double)
+
+  def apply(v: JVar): SpssVariable = SpssVariable(
+    name = v.getVariableName,
+    shortName = v.getShortName,
+    isNumeric = v.isNumeric,
+    index = v.getIndex,
+    label = v.getVariableLabel,
+    missingRange = if (v.isHasMissingRange)
+      Some((v.getMissingMin.doubleValue(), v.getMissingMax.doubleValue()))
+    else None,
+    missing = v.getMissing.asScala.map(_.doubleValue()).toList,
+    missingStrings = v.getMissingStrings.asScala.toList,
+    labels = v.getValueLabels.asScala.map { case (k,x) =>
+      (k.doubleValue(), x) } toMap)
+}