1

When importing tabular data as Import["URL","Data"], it is often the case that Mathematica will skip returning values for tables in which an entry in the table is blank. For example, in importing some election results from "https://www.presidency.ucsb.edu/statistics/elections/2020", after suitably editing using part and flatten the table to only include relevant data of election results by state, it can be seen that electoral votes are always being imported as type Integer, whereas all other entries are of type String. Thus, even though this creates 56 x 9 matrix, the values in the columns do not coincide by type as desired.

Taking the data for the first 5 states in the list for brevity in this example, the data look like this.

byStatePresidentialVotesData2020 = {{"Alabama", "2,323,282", "849,624", "36.57%", "1,441,170", "62.03%", 
  9, "32,488", "1.40%"}, {"Alaska", "359,530", "153,778", "42.77%", 
  "189,951", "52.83%", 3, "15,801", "4.39%"}, {"Arizona", "3,387,326",
   "1,672,143", "49.36%", 11, "1,661,686", "49.06%", "53,497", 
  "1.58%"}, {"Arkansas", "1,219,069", "423,932", "34.78%", "760,647", 
  "62.40%", 6, "34,490", "2.83%"}, {"California", "17,500,881", 
  "11,110,250", "63.48%", 55, "6,006,429", "34.32%", "384,202", 
  "2.20%"}}

Consequently, I need to add an additional column conditionally either at position 5 or 8 depending on where electoral votes have been left blank in the data as imported.

With column headers (modified to avoid redundant key names) as:

 headers = {"STATE", "TOTAL VOTES", "Votes D", "% D", "EV D", "Votes R", "% R", "EV R", "Votes Others", "% Others"}

this would then permit an association of associations to be built using AssociationThread, for 10 rather than 9 columns, but with appropriate headers suitably aligned.

Because electoral votes are always given as of type Integer, I need to insert a 0 (Integer Zero) into column 5 for those rows for which column 5 is a String, since the entry of the column after a blank column will be of type String rather than Integer and insert a 0 (Integer 0_ at position 8 with a 0 (Integer Zero) for which column 5 is an Integer.

To do this I created the following conditional expression:

If[IntegerQ[Head[byStatePresidentialVotesdData2020[[#, 5]]]], 
   Insert[byStatePresidentialVotesdData2020[[#]], 0, 8], 
   Insert[byStatePresidentialVotesdData2020[[#]], 0, 5]] & /@ 
 Range[Length[byStatePresidentialVotesData2020]]

Unfortunately, rather than inserting columns conditionally, it always inserts a 0 in column 5 even for the rows for "Arizona" and "California", where a zero should have been entered in column 8 instead, even though the Head for the 5th entry in these lists are of type "Integer".

In[221]:= Head[byStatePresidentialVotesData2020[[#, 5]]] & /@ Range[5]

Out[221]= {String, String, Integer, String, Integer}

Can anyone explain why this code fails and how it might be modified to appropriately do the conditional insert as intended?

Stuart Poss
  • 1,883
  • 9
  • 17
  • Trying to understand it: How about (If[Head[Part[#, 5]] === String, Insert[#, 0, 5], If[Head[Part[#, 5]] === Integer, Insert[#, 0, 8], #]] & /@ byStatePresidentialVotesData2020 ) // TableForm ? – Syed Feb 12 '23 at 18:43

2 Answers2

2

To make things more readable, I would define a function, that takes one row, makes the necessary replacement and returns the result. Then this function can be mapped (for short:/@) onto your data:

f[d0_] :=  Module[{d = d0}, Switch[Head[d[[5]]], String, d = Insert[d, 0, 5], Integer, d = Insert[d, 0, 8]]; d];

result = f /@ byStatePresidentialVotesData2020; result // TableForm

enter image description here

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57
2

I will convert my comment into an answer.

byStatePresidentialVotesData2020 = {{"Alabama", "2,323,282", 
   "849,624", "36.57%", "1,441,170", "62.03%", 9, "32,488", 
   "1.40%"}, {"Alaska", "359,530", "153,778", "42.77%", "189,951", 
   "52.83%", 3, "15,801", "4.39%"}, {"Arizona", "3,387,326", 
   "1,672,143", "49.36%", 11, "1,661,686", "49.06%", "53,497", 
   "1.58%"}, {"Arkansas", "1,219,069", "423,932", "34.78%", "760,647",
    "62.40%", 6, "34,490", "2.83%"}, {"California", "17,500,881", 
   "11,110,250", "63.48%", 55, "6,006,429", "34.32%", "384,202", 
   "2.20%"}};

headers = {"STATE", "TOTAL VOTES", "Votes D", "% D", "EV D", "Votes R", "% R", "EV R", "Votes Others", "% Others"};

(estats = 
   If[Head[Part[#, 5]] === String, Insert[#, 0, 5], 
      If[Head[Part[#, 5]] === Integer, Insert[#, 0, 8], #]] & /@ 
    byStatePresidentialVotesData2020 ) // TableForm

Prepend[estats, headers] // Grid[# , Alignment -> {{Left, {Center}}, Center} , Frame -> All , Background -> {{None, None}, {Cyan, White}} , Spacings -> {1, 1} ] &

enter image description here

Syed
  • 52,495
  • 4
  • 30
  • 85
  • 1
    Very complete answer. The additional explanation clearly worked through the problem in an understandable way. Now straightforward to convert this to a dataset. Sorry for the delay in responding. A hand injury has limited my keyboard time. – Stuart Poss Jun 19 '23 at 03:34