Skip to main content

#Now0 discutindo

I have text contain many word starting with #, I want to to split all of these and use as a dimension, is it possible in tableau? In Qlik Sense I used Subfield to slove this case.

 

Can anyone help me, thanks in advance.

 

Examples:

Row1: ⌗breakfast noodle ⌗paypal

Row2: ⌗breakfast sandwich ⌗airpay ⌗now

Row3: ⌗forwork ⌗hsbc license fee

Row4: ⌗airpay ⌗now coffee passio

 

I want get them as dimensions look like below (in 1 column & not include value after blank space):

⌗breakfast

⌗paypal

⌗forwork

⌗hsbc

⌗airpay

⌗now

 

Note:

  • Number of hashtag will be add-in frequently, not fix in a list.
  • Using Tableau Desktop & Prep
  • Edit title & add-in some information to make my question more clearly.
6 respostas
  1. 13 de jul. de 2020, 13:24

    Hi, here are some answers:

     

    re: keeping first word of each hashtag - after you do the pivot operation then do one more split on space to get the first word.

     

    re: the data size increasing & complexity. One piece is to filter out any Null rows added through the workaround, the second is that this is changing the data structure from "one record per social media post" to "one record per hashtag" and yes, you're getting more records out of this. You didn't say how many records you have nor what kind of analysis you are trying to do so I'm not sure how much of an issue that really is given how performant Tableau can be.

     

    In any case there are three methods for working with this:

     

    1) Output the "one record per social media post & hashtag" aka pivoted data set and use COUNTD() or Level of Detail expressions when you want to do analysis at the social media post level.

     

    2) Output the pivoted data and output an unpivoted data set and connect them as two different data sources in Tableau Desktop. Use the pivoted data when you need to do the per hashtag analysis and use the unpivoted data for all other analysis, and use cross data source filters and/or filter actions to make it appear to the user that they are working with a single data set. In this use case the measures would be using COUNT() or SUM(Number of Records]).

     

    3) Tableau v2020.2 adds the relationships feature that is a new way of connecting data sets. In this use case you'd still output the pivoted & unpivoted data, with two changes being that 1) the pivoted data would only have the post id & hashtag. Then 2) Instead of connecting as two separate data sources you'd relate them as two logical tables on the post id. Then you could use COUNT() or COUNT(logical table) and Tableau would automatically resolve the level of detail issues (this is part of the functionality of relationships) and you wouldn't have to use cross data source filters or filter actions (because instead of having two Tableau data sources there's just one).

     

    Jonathan

0/9000

The data I have are in separate text files as csv's.

A csv cannot have multiple worksheets in it.

I'm adding all the csv tables (4 in total) and making it one combined source.

Then I add a separate new table a try to left join the one combined source to the new table.

The result is it only joins with one csv table because the added csv files won't combine into one source.

 

I'm adding the files as follows:

File -> New

Connect to data: Text File -> point to first .csv -> OK -> Import All Data -> Save Extract

Right click on Extract -> Add Data From File ... -> Choose 2nd txt file.  Should get "x rows successfully added."

(repeat as needed, but try adding 2 files and see what happens)

Data -> Connect to Data... -> Text File -> point to join file -> Ok -> Import all Data -> Save Extract

 

Attached is an example. If I left join the book1 with prod_info across prod and product....it cuts off the dates it joins to only october and not oct-dec.

13 respostas
  1. 25 de nov. de 2013, 18:53

    Here is a custom sql that works on my computer. I had some localization issues, which were solved by creating a schema.ini file in the same folder.

    .

    SELECT d.date,

      d.store,

      d.qty,

      d.product,

      p.height,

      p.length,

      p.width,

      p.[case qty]

    FROM (

      SELECT [date],

        [store],

        [qty],

        [product]

      FROM [Book1#csv]

      UNION ALL

      SELECT [date],

        [store],

        [qty],

        [product]

      FROM [Book2#csv]

      UNION ALL

      SELECT [date],

        [store],

        [qty],

        [product]

      FROM [Book3#csv]

      ) d

    LEFT JOIN [prod_info#csv] p ON d.product = p.prod

    .

0/9000

Hi all-

    I'm working on my first TabPy integration and have run into a problem.  I do not think I understand how to properly send each individual data row to my pickled python model.

I have attached a writeup below, my Tableau workbook (10.4.6),  my pickled model (created with Python 2.7, you need to unzip it), the input dataset, and a small bit of Python code you can use to test the pickled model on the input dataset outside of Tableau.   I was inspired by  Bora Beran and his article

and thought I would give it a try.

    TabPy is super cool and I seem to be very close to getting it to work.  I would love to give this Tableau report to a user and let them update the IVR system to save $$ on calls. My estimate shows that about 10% of our calls could be switched to IVR and we would still get the same number of orders. The algorithm is returning a cross validation score of 88% with 5 folds so it seems pretty accurate.

 

I’d love to get this working completely in Tableau so I can show off the wonders of Tableau. Otherwise I’ll just submit a boring spreadsheet with a list of patients/calls that could be switched to IVR.

Thanks for all your help.

Cheers,

Eric

 

Dataset:

The dataset has a list of communication records.  Each record represents a communication to a patient.  The sample data communications all have a MODALITYCODE of “5” which represents an in person call made by a customer service representative.

COMMSID is a unique row identifier to represent that particular communication record.

 

Machine Learning Model:

I have trained and created a machine learning model (a DecisionTree) in Python.  I saved the model to a file (a pickle) .

It is accessible via TabPy and the calculated field (“PredictionOnModality”)

 

Tableau Goal:

In Tableau I want to pass all the individual records to my algorithm and have it predict if an order will be made IF we change the MODALITYCODE=4.  MODALITYCODE 4 is a call from our automated IVR system and is much cheaper than the MODALITYCODE 5 customer service call.

 

The columns of data that my model uses to make the prediction are:

Column

Values

VALIDPHONE

1 or 0.  1 means we have a known working phone number for the patient.

MODALITYCODE

The type of outbound call made to the patient.  4 for IVR, 5 for customer service/human call

NUM_OF_PREV_ORDS

The number of order the patient has previously placed with us.

NUM_OF_PREV_COMMS

The number of communications the patient has previously had with us.

DAYS_SINCE_LAST_COMMS

The number of days since the patient was last contacted.

BIRTHYEARMASKED

The Birth Year of the patient.

CONTACTTEAM

We have two teams that can place calls.  1 is for team 1 and 2 is for team 2.

PATIENT_COMMS_HOUR

Is the hour we made the call at using military time: 0 for midnight up to 23 for 11:00 PM.

 

Setup in Tableau:

I pass all the above columns from the dataset to my algorithm except for the MODALITYCODE. Instead of passing the MODALITYCODE from the dataset, I created a parameter called P2_MODALITYCODE and set it to 4.  Using this parameter, my algorithm can predict if the patient would make a purchase if we called them using the IVR system rather than the more expensive in person customer service call.

 

Here is my calculated Tableau field that passes the data and uses my algorithm.  This is a TabPy integration and the column is called “PredictionOnModality”.  It returns a “1” is the patient will place an order or a 0 if the patient will not place an order.

SCRIPT_INT(

"import pickle

import numpy as np

pickle_in = open('C:\pp\BTResupply\code\main\simple.27.pickle','rb')

model = pickle.load(pickle_in)

X= np.array([[_arg1[1], _arg2[1], _arg3[1], _arg4[1], _arg5[1], _arg6[1], _arg7[1], _arg8[1]]])

prediction_set = model.predict(X)

return prediction_set.tolist()",

attr([Validphone]),[P2_MODALITYCODE],attr([NUM_OF_PREV_ORDS]),attr([NUM_OF_PREV_COMMS]),

attr([DAYS_SINCE_LAST_COMMS]),attr([Birthyearmasked]),attr([Contactteam]),attr([Patient Comms Hour])

)

 

My Issue:

@

I don’t think I’m passing the data row by row correctly to my Python algorithm.    I’m getting predictions made (the integration is working) but it sort of looks like if any row predicts a “0” for "PredictionOnModality", then  all rows will show a 0.  If any row predicts a “1” then all rows will show a “1”.

I opened a support case but support told me they do not support TabPy and I can try the community or professional services.

 

Tableau ScreenShot:

How to pass each row of data from Tableau to a Python model to make predictions for each row

 

5 respostas
  1. 29 de jun. de 2018, 18:53

    Ah! Your second comment helped me figure out what was going wrong here. TabPy and the model you've built expect data in lists/arrays. In your code, you are filtering each list to the index 1 (ie _arg1[1]), which is the second value in the python indexing system 0,1,2... which is why you are always seeing the second row's values. This code should execute as expected:

     

    SCRIPT_INT(

    "import pickle

    import numpy as np

    pickle_in = open('C:\pp\BTResupply\code\main\simple.27.pickle','rb')

    model = pickle.load(pickle_in)

    X= np.array([[_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8]])

    prediction_set = model.predict(X)

    return prediction_set.tolist()",

    attr([Validphone]),[P2_MODALITYCODE],attr([NUM_OF_PREV_ORDS]),attr([NUM_OF_PREV_COMMS]),

    attr([DAYS_SINCE_LAST_COMMS]),attr([Birthyearmasked]),attr([Contactteam]),attr([Patient Comms Hour])

    )

     

    To answer your more general question, TabPy does not currently have a way to pass truly row level data. Since the SCRIPT_* functions in Tableau to pass code are table calculations, they will operate on what is in the visual level of detail. In this case, you are able to make the visual level of detail the row level by adding COMMSID to the view. Would being able to pass row level data without having it on the view be useful to you?

0/9000

I'm not sure the best way to put this into words, so I wrote it out in what I hope is an English legible pseudo code. # denotes a comment for explanation purposes. I've been trying to do this in tableau with LOD descriptions, for example {FIXED [Subscriber ID]:COUNT([Subscriber ID])} counts the number of instances of the same ID but it doesn't exclude those not made within 24 hours of one another. Any help would be greatly appreciated

 

for each entry:

     get list of all other entries with same UserID

          for each entry in list:

               if thisEntry.date-entryWithSameUserID.date < 24 hours:

                    add to resultsList

                    break

 

⌗now I have a results list with a bunch of entries that were logged

⌗within 24 hours of one another from the same user ID

⌗note that if a user made 2 entries in our data base on 1/1/2019

⌗and then the same user made 2 entries in our data base on 2/2/2019

⌗the same user would be in our results list multiple times for the

⌗two seperate occasions that s/he made multiple purchases within 24 hours

 

for each entry in resultsList

     ⌗get how many entries were made within a 24 hour period per ID

     Count instances of each ID

 

     ⌗get which purchases led to more purchases within 24 hours

     ⌗ex. if someone buys a puppy, are they likely to also buy a bed within 24 hours?

     ⌗ex. if someone buys a puppy, are they likely to also buy a bed AND food within 24 hours?

     for each set of purchases made within 24 hours

          count which purchases were made with the earliest date

3 respostas
  1. 1 de mai. de 2019, 19:52

    The relative date will consider the computer date (unless you specify at the bottom that the date is relative to a specific date).

     

    But this can cause problems if your data is not updated. If someday you don't have your data refresh done the dashboard will appear empty (which is never good).

     

    To address that I had to apply something like this LOD on a dashboard I built:

     

    {FIXED [Dimension] :

        SUM(IIF(DATETRUNC('day', [Date]) = [MAX Date],[Measure],NULL))

    }

     

    And the MAX Date field is just a check on your MAX(Date) (which you can define as anything you want). For me it looks like this:

     

    DATE({MAX([Date])})

     

    I hope these helps.

    Rodrigo

0/9000

#Now IT Matters is excited to welcome our newest Nimja, @Amanda Byrne !! Amanda will be coming on at NiM in the next few weeks - we're so excited about the knowledge and enthusiasm she'll bring to our team!! Welcome & congrats, Amanda!! 🙂

@Tim Lockie 

@Angela (Ang) Adams 

@Justin Barss 

@Warren Wade 

@Todd Hash 

@Christine Tellez 

0/9000

Hi,

 

Am using Tableau Data API with P Python and creating a .tde. It has worked well apart from when I try to rerun the Python and I get the following error:

 

Traceback (most recent call last):

File "//psf/Home/Desktop/Google Sreadsheet2", line 30, in <module>

   table = tdefile.addTable('Extract',tableDef)

File "C:\Python27\lib\site-packages\dataextract\Base.py", line 484, in addTable

   raise Exceptions.TableauException(result, wstring_at(tablib.TabGetLastErrorMessage()))

TableauException: TableauException (303): duplicate table name”

 

'Extract' is the duplicate table name, but by default has to be the table name, so when you are doing an automatic refresh you get the error? Anyway out of this, or a better method of getting random APIs

 

Code below

 

Thanks in aADvance:

 

import os, datetime

import dataextract as tde

import gspread

import schedule

import time

 

#Step 1: Create the extract file

try:

    tdefile = tde.Extract('GG11.tde')

except:

    os.remove('GG11.tde')

    os.remove('DataExtract.log')

    tdefile = tde.Extract('GG11.tde')

 

#Step 2: Connect to the Google Spreadsheet and put the data in a list of lists

gsclient = gspread.login(

spreadsheet = gsclient.open_by_key('0')

worksheet = spreadsheet.get_worksheet(0)

data = worksheet.get_all_values()

 

#Step 3: Create the tableDef and the table

try:

    tableDef = tde.TableDefinition()

except:

    os.remove()

    tableDef = tde.TableDefinition()

   

tableDef.addColumn('number', tde.Type.CHAR_STRING)

try:

    table = tdefile.addTable('Extract',tableDef)

 

#Step 4: Loop through our list of lists of data,

#   put it into rows, and insert the rows

newrow = tde.Row(tableDef)

for row in data[10:]:

    newrow.setCharString(0,row[2])

table.insert(newrow)

 

#Step 5: Close the tde

tdefile.close()

3 respostas
  1. 5 de mar. de 2014, 23:55

    Hi Ranjit,

     

    I have been getting this duplicate table name error too.

     

    My solution:

    Check for and delete the existing extract BEFORE using the dataextract.Extract() method.

     

    So my original code was this:

    ###########⌗BAD############

    # ⌗create the extract

    # try:

    #     ⌗try to create the extract file

    #     tdefile = tde.Extract(dataFolder+'DataExtract.tde')

    # except:

    #     ⌗if the file already exists, delete it

    #     os.remove(dataFolder+'DataExtract.tde')

    #     ⌗create the file now

    #     tdefile = tde.Extract(dataFolder+'DataExtract.tde')

     

    My new, working code does this:

    ###########⌗GOOD############

    ⌗if the extract already exists, delete it.

    if os.path.isfile(dataFolder+'DataExtract.tde'):

      os.remove(dataFolder+'DataExtract.tde')

    ⌗now create a new one

    tdefile = tde.Extract(dataFolder+'DataExtract.tde')

     

    Hopefully this helps!

0/9000