3
$\begingroup$

First of all, I cannot think of a better title for this question.

I have a csv file, snippet, which is encoded in Japanese. I used the following code to import and it could correctly show the column head, at least, not some random characters.

Import["ETC_1.csv","Dataset",CharacterEncoding->"ShiftJIS",HeaderLines->1]

I then wanted to do some calculation: col4-col2 (after convert them to TimeObject), which I know is the ending and starting time of a travel. However, I do not know how to type in Japanese, which means I cannot type the "column_head" when write a function or query, e.g. #head to do so. I then tried to extract the Keys with the following code.

dataset[All, (Slot[Normal[dataset[1, Keys]][[1]]] - Slot[Normal[dataset[1, Keys]][[2]]]) &]

But it did not work and showed the following error message.

Function::slot: Slot[Normal[dataset[1,Keys]][[1]]] (in Slot[Normal[dataset[1,Keys]][[1]]]-Slot[Normal[dataset[1,Keys]][[2]]]&) should contain a non-negative integer or string.

Could anyone please show me a way to implement this function either by using the column head or column number and also please show me why I have the above error? Thanks.

$\endgroup$
1
  • $\begingroup$ I would convert the Dataset to an Association. Then it is straight forward to either get the keys through the Keys function. Or just continue and extract the values and last use Part and the 3rd and 4th column. Doing non trivial computations with Dataset always confuses me. $\endgroup$
    – FredrikD
    Apr 17 at 15:23
3
$\begingroup$

The issue is that slot syntax within a function is restricted to constant values only, literal integers or strings. This is a restriction of Function itself, whether or not it is used to query a Dataset:

Slot["a"~~"b"] &

Function: Slot[a~~b] (in Slot[a~~b]&) should contain a non-negative integer or string.

In the case at hand, we can evaluate the key expressions and inject them as constants using With:

With[{k4 = Normal@dataset[1, Keys][[4]], k2 = Normal@dataset[1, Keys][[2]]}
, dataset[All, TimeObject@Slot[k4] - TimeObject@Slot[k2]&]
]

dataset with time intervals

We may want to hoist out the common subexpression (the second version uses an undocumented form of With):

With[{keys = Normal@dataset[1, Keys]}
, With[{k4 = keys[[4]], k2 = keys[[2]]}
  , dataset[All, TimeObject@Slot[k4] - TimeObject@Slot[k2]&]
  ]
]


With[{keys = Normal@dataset[1,Keys]}, {k4 = keys[[4]], k2 = keys[[2]]}
, dataset[All, TimeObject@Slot[k4] - TimeObject@Slot[k2]&]
]

Simpler Alternative?

Since the operations are being expressed positionally anyway, we might consider a simpler alternative using Part syntax:

dataset[All, TimeObject@#[[4]] - TimeObject@#[[2]]&]

dataset with time intervals

$\endgroup$
1
  • $\begingroup$ Thank you so much. I thought it could be related to the value passed to Slot is not evaluated and wrapped it with Evaluate before passing to Slot. However, it did not work. I did not realize that I can use With to do the same thing. Also, I understand the Slot syntax better now thanks to your answer. Finally, I really like the undocumented With feature you used above and the simpler alternative. Thanks again! $\endgroup$
    – Bemtevi77
    Apr 18 at 0:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.