3
$\begingroup$

I have the following string dataset:

{{22/03 updating, 55.218 (+1.640), 44.321 (+1.640), 4.825 (+0), 6.072 (+0), details},
{21/03, 53.578 (+6.557), 42.681 (+4.821), 4.825 (+793), 6.072 (+943), details}, 
{20/03, 47.021 (+5.986), 37.860 (+4.670), 4.032 (+627), 5.129 (+689), details}, 
{19/03, 41.035 (+5.322), 33.190 (+4.480), 3.405 (+427), 4.440 (+415), details}}

I cleaned part of it by deleting details with Drop, but I cannot erase the brackets terms (+...) and the updating term at the same manner. Is it possible delete (+...) and updating terms by using Map with some functions like StringPartReplace (with: "") or StringDelete, in combination with StringCases or similar ?

$\endgroup$
1
  • $\begingroup$ Can you show us what did you try? $\endgroup$
    – Victor K.
    Mar 22 '20 at 17:20
1
$\begingroup$

There could be many different solutions. Here is one which assumes that your inputs are either two (or more fields) separated by space, such as "22/03 updating", "55.218 (+1.640)" or a single field (such as "details") that should be ignored:

extract[s_String] := Module[{fields = StringSplit[s, " "]},
  If[Length[fields] > 1, First[fields], Nothing]]

returns

extract /@ {"22/03 updating", "55.218 (+1.640)", "44.321 (+1.640)", 
  "4.825 (+0)", "6.072 (+0)", "details"}
{"22/03", "55.218", "44.321", "4.825", "6.072"}

Just to illustrate how you can process this further (the process function is not very robust):

process[s_String] := 
 If[StringContainsQ[s, "/"], DateObject[s], ToExpression[s]]

enter image description here

The resulting list consists of a DateObject, followed by a list of numbers, as you can verify with FullForm:

FullForm[%]

List[DateObject[List[2020,3,22,0,0,0],"Instant","Gregorian",-7.`],
  55.218`,44.321`,4.825`,6.072`]

Update. Now that you have clarified (in comments) what specific data you are looking at, we can make the extraction more robust:

data = Import["https://statistichecoronavirus.it/coronavirus-italia/", "Data"];
process[s_String] := Module[{d = StringSplit[s, " "][[1]]},
  If[StringContainsQ[d, "/"], DateObject[{d <> "/2020", {"Day", "/", "Month", "/", "Year"}}], 
   ToExpression[StringReplace[d, "." -> ""]]]]
process[s_Integer] := s (* to process the last string *)
Map[process, data[[2, All, ;; -2]], {2}] // Dataset

enter image description here

$\endgroup$
8
  • $\begingroup$ Thank you Victor! I succeded in applying the combination of the two function just for each row of my list, is it possible to apply it to the entire matrix I have? $\endgroup$
    – Nate
    Mar 22 '20 at 19:29
  • $\begingroup$ Sure. Let's say you have a matrix m = Table[RandomInteger[{1, 100}], 10, 10] and a function f that you want to apply to each element of the matrix. Using a third optional argument of Map, you can apply f to each element of m: Map[f,m,{2}] $\endgroup$
    – Victor K.
    Mar 22 '20 at 19:39
  • $\begingroup$ I don't understand if something doesn't work. I tried with Map[extract,d,{2}] and the result is: `{{22/03 updating, 55.218 (+1.640), 44.321 (+1.640), 4.825 (+0), 6.072 (+0), details}, {21/03, 53.578 (+6.557), 42.681 (+4.821), 4.825 (+793), 6.072 (+943), details}, {20/03, 47.021 (+5.986), 37.860 (+4.670), 4.032 (+627), 5.129 (+689), details}, {19/03, 41.035 (+5.322), 33.190 (+4.480), 3.405 (+427), 4.440 (+415), details}} $\endgroup$
    – Nate
    Mar 22 '20 at 20:05
  • $\begingroup$ @Mick it's really hard to debug remotely :). Could you please do the following; 1) copy your definitions for d and extract into a separate notebook. 2) publish this notebook online (for free - see blog.wolfram.com/2019/10/24/…), 3) share here as a comment - I will try to have a look $\endgroup$
    – Victor K.
    Mar 22 '20 at 21:17
  • $\begingroup$ wolframcloud.com/obj/ad9ea091-6d37-42e9-807a-2eed234de088 $\endgroup$
    – Nate
    Mar 22 '20 at 21:57
1
$\begingroup$

Solved - by naming the dataset d - with:

try = Table[StringExtract[Drop[d[[i]], -1], 1], {i, 1, Length[d]}]

I get the desidered output:

{{"22/03", "55.218", "44.321", "4.825", "6.072"}, {"21/03", "53.578",  "42.681", "4.825", "6.072"}, {"20/03", "47.021", "37.860", "4.032", "5.129"}, {"19/03", "41.035", "33.190", "3.405", "4.440"}}

Anyway, really interested in possible solutions with Map because I already have a list and I think should be more suitable instead of using Table. Moreover, the solution is incomplete because if, for instance, I have a string term with just one part (that is, without (+...), I obtain an error on that string output.

$\endgroup$
1
  • $\begingroup$ Table is not the best solution, for number of reasons - it's better to define your extraction logic more clealry and use a Map as in my solution. Btw, Most returns all the elements of the list except the last one, so Most[Range[5]] returns {1,2,3,4}; it's a bit more clear than Drop[Range[5],-1] which accomplishes the same. $\endgroup$
    – Victor K.
    Mar 22 '20 at 18:54

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.