A dataset
A dataset
The following dataset is a small snippet of a large list of datasets imported from an Excel Workbook. Each dataset in the list is imported from a separate worksheet in the Excel workbook. The Excel worksheet contents are all different. But they share a common structure. The top three rows of each worksheet define column headings (the dataset keys), data type codes and unit names. Subsequent rows, 4 onwards, contain the data values. All data values are stored in Excel (and imported into Mathematica) as strings.
Note that the data type codes and unit names (rows 2 and 3 of the Excel worksheet respectively) are excluded from the dataset snippet.
In[]:=
ds=
Out[]=
Get the dataset keys (or column headings)
Get the dataset keys (or column headings)
In[]:=
keys=ds//First//Keys//Normal
Out[]=
{locaId,isptTop,isptSeat,isptMain,isptNpen,isptNval,isptRep}
Define codes that define the type of each column in the dataset
Define codes that define the type of each column in the dataset
In[]:=
types={"ID","2DP","0DP","0DP","0DP","0DP","X"};
Code “ID” denotes columns containing String values.
Codes ending in “DP” denote columns containing decimal number values.
Code “X” denotes columns containing String values.
Define a function that converts numeric string values based on the type codes
Define a function that converts numeric string values based on the type codes
In[]:=
ClearAll[toType]toType[type_String,""]:=Missing[]toType[type_String,x_Missing]:=Missing[]toType[type_String/;StringEndsQ[type,"DP"],x_String]:=ToExpression[x]toType[type_String/;StringEndsQ[type,"SF"],x_String]:=ToExpression[x]toType[type_String/;StringEndsQ[type,"SCI"],x_String]:=Interpreter["Number"][x]toType[type_String/;StringMatchQ[type,"U"],x_String]:=Interpreter["Number"][x]toType[type_String,x_String]:=x
Build an expression to be used in converting string values to numeric values
Build an expression to be used in converting string values to numeric values
In[]:=
expression=Table[keys[[i]]->toType[types[[i]],Slot[keys[[i]]]],{i,Length@keys}]
Out[]=
{locaIdtoType[ID,#locaId],isptToptoType[2DP,#isptTop],isptSeattoType[0DP,#isptSeat],isptMaintoType[0DP,#isptMain],isptNpentoType[0DP,#isptNpen],isptNvaltoType[0DP,#isptNval],isptReptoType[X,#isptRep]}
Use the above expression to convert string values in the dataset to numeric values
Use the above expression to convert string values in the dataset to numeric values
Using the variable expression does not work – see below.
In[]:=
ds[All,Association[#,expression]&]
Out[]=
But, when I copy the evaluated form of expression and paste it into the above block of code, I get the desired result – see below.
In[]:=
numeric=dsAll,Association#,&
Out[]=
Unfortunately, copying and pasting the evaluated form of expression is not a viable solution for this use case so I want to figure out a way to achieve the above result programmatically.
Eric’s solution
Eric’s solution
In[]:=
keyType=MapThread[(#1->#2)&,{keys,types}]
Out[]=
{locaIdID,isptTop2DP,isptSeat0DP,isptMain0DP,isptNpen0DP,isptNval0DP,isptRepX}
In[]:=
ClearAll[typedVal]typedVal[type_String,""]:=Missing["Empty string",type];typedVal[type_String?(StringEndsQ[{"DP","SF"}]),val_String]:=ToExpression[val];typedVal[type_String?(StringEndsQ[{"SCI","U"}]),val_String]:=Interpreter["Number"][val];typedVal[type_String,val_]:=val
In[]:=
toTypedPair[key_String,val_]:=key->typedVal[key/.keyType,val]
In[]:=
eric=ds[All,Association@*KeyValueMap[toTypedPair]]
Out[]=
Check that the numeric values have been properly converted
Check that the numeric values have been properly converted