How to resolve duplicate column names in excel file with Alteryx? - alteryx

I have a wide excel file with price data, looking like this
Product | 2015-08-01 | 2015-09-01 | 2015-09-01 | 2015-10-01
ABC | 13 | 12 | 15 | 14
CDE | 69 | 70 | 71 | 67
FGH | 25 | 25 | 26 | 27
The date 2015-09-01 can be found twice, which in the context is valid but obviously messes up my workflow.
It can be understood that the first value is the minimum price, the second one the maximum price. If there is only one column, min and max are the same.
Is there a way to resolve this issue?
An idea I had was the following:
I also have cells that contain a value like "38 - 42", again indicating min and max. I resolved this by spliting it based on a Regex expression. What could be a solution is to join two columns that have the same header, to afterwards split the values according to my rules. That however would require me to detect dynamically if the headers are duplicates.
Is that something that is possible in Alteryx or is there an easier solution for this problem?
And of course asking the supplier of the file to change it is not really an option, unfortunatelly.
Thanks
EDIT:
Just got another idea:
I transpose the table to have the format
Product | Date | Price Low | Price High
So if I could check for duplicates in that table and somehow merge these records into one, that would do the trick as well.
EDIT2:
Since I seem to haven't made that clear, my final result should look like the transposed table in EDIT1. If there is only one value it should go in "Price Low" (and then I will probably copy it to "Price High" anyway. If there are two values they should go in the according columns. #Poornima's suggestion resolves the duplicate issue in a more sophisticated form than putting a "_2" behind the column name, but doesn't put the value in the required column.

If this format works for you:
Product | Date | Price Low | Price High
Then:
- Transpose with Product as a key field
- Use a select tool to truncate your Name field to 10 characters. This will remove any _2 values that Alteryx has automatically renamed.
- Summarize:
Group by Product
Group by Name
Then apply Min and Max operations to value.
Result is:
Product | Name | Min_Value | Max_Value
ABC | 2015-08-01 | 13 | 13
ABC | 2015-09-01 | 12 | 15
ABC | 2015-10-01 | 14 | 14

For this problem, you can leverage the native Excel (.xlsx) driver available in Alteryx 9.1. If multiple columns in Excel use the same string, then they are renamed by the native driver with an underscore at the end e.g., 2015-09-01, 2015-09-01_1. By leveraging this, we can reformat the data in three steps:
As you suggested, we start by transposing the data so that we can leverage the column headers.
We can then write a formula with the Formula Tool that evaluates whether the column header for the date is the first or the last one based on the header length.
The final step would be to bring the data back into the same format as before, which can be via the Crosstab Tool.
You can review the configurations for each of these tools here. The end result would be as follows.
Hope this helps.
Regards,
Poornima

Related

Dynamic Data Validation lists based on VLookup

I'm trying to add a custom 'discount' list to my spreadsheet.
I've got a table that contains all the data, and has costs for the standard 'used' value, then also the values at a 5% discount and a 10% discount.
Example:
+---------+-------------------+------+------------+-------------+
| Code | Role | Used | Used - 5% | Used - 10% |
+=========+===================+======+============+=============+
| Test001 | Employee | 5.67 | | |
+---------+-------------------+------+------------+-------------+
| Test002 | Junior Technician | 9.80 | 9.31 | 8.38 |
+---------+-------------------+------+------------+-------------+
| Test003 | Project Manager | 15 | | |
+---------+-------------------+------+------------+-------------+
| Test004 | Engineer | 20 | 19 | 17.10 |
+---------+-------------------+------+------------+-------------+
I've then got a Data validation list which returns all other the 'Roles' to select from. On the back of this this populates the Cost cell.
Example:
+----------+----------+----------+-------+
| Role | VLOOKUP | Discount | Cost |
+==========+==========+==========+=======+
| Employee | | | 5.67 |
+----------+----------+----------+-------+
| Engineer | 5%,10% | 10% | 15.10 |
+----------+----------+----------+-------+
What I want to do is have a list to be populated with 5%, 10% if there is that option. I'd like to achieve this without vba (I could easily achieve this with vba but trying to keep it all in the worksheet)
My VLOOKUP Column is populated using:
=CONCATENATE(IF(VLOOKUP(A2,INDIRECT("Test[[Role]:[Used - 10%]]"), 3, FALSE) <> "", "5%", ""),
IF(VLOOKUP(A2,INDIRECT("Test[[Role]:[Used - 10%]]"), 4, FALSE) <> "", ",10%", ""))
The issue comes when trying to do the data validation. It accepts the formula (tried using the above to no avail in the data validation) but populates the drop down list with just the one value of 5%,10% instead of interpreting it as a csv.
I'm currently using this to attempt to populate the Discount Drop Down
=OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0, -1)
It is possible assuming your version of Excel has access to the dynamic functions FILTER and UNIQUE. Let's go through a couple of things, and here is a google doc where this is demonstrated. I also included an online excel file*.
It isn't necessary to calculate the cost in the setup table (A:E). You can just use a character to mark availability (and in some versions it was difficult to make the FILTER work with comparisons like <>"", etc, when ="x" worked fine).
You can get an array of available discounts by using FILTER, INDEX and MATCH. See Col P. You use INDEX/MATCH to return a single row of the array containing the discounts (in this case D:E), and then use that row to filter the top row (D1:E1) which has the friendly discount names and return it as an array.
It isn't necessary to concat the discount list the way you're doing. You can use TEXTJOIN, FILTER, INDEX and MATCH. See Col I. You just wrap the calculation that generates the array of discount names (step 2) in TEXTJOIN to get a string.
The validation is accomplished by referencing the output of step 2. I don't think that the data validation dialog can handle the full formula, so I pointed it to Cols O:Q. Col O is included in the validation so that you can get an empty spot at the top of the list, but Google Docs seems to strip it out.
You can just calculate the discounted cost from the selected option. See Col K. I included the original cost in Col L so you can see it.
you will need a microsoft account to view

PowerPivot transpose column headers on rows

I have two datasources, one comes from an excel file i cannot change with this format
item | week 1 | week 2 | ...
ITM01| 12 | 23 | ...
My second datasource comes from a query and looks like
item | Week | Value
ITM01| 1 | 5
ITM02| 2 | 10
...
I need to merge the two tables to have, hopefully, something like
item | Week | Value 1 | Value 2
ITM01| 1 | 5 | 12
ITM01| 2 | 10 | 23
...
I'd like to achieve this in powerpivot, considering that I cannot change the excel datasource, and i would like it to be updateable by using excels refresh button, which means, i think, that i should not create custom tables to handle the transposition, as that might ruin the refresh.
I'm really lost on how to achieve this and some help would be much appreciated.
I'd also add that i can change the second data source to look like the first one(weeks on columns), but while i might be able to connect the two tables, i would still not know how to achieve the desired output with weeks on rows.
Thanks a lot for your time.

Count number of rows where multiple criteria are met

I'm trying to generate a table that shows a count of how many items are in any given status on any given day. My result table has a set of Dates down column A and column headers are various statuses. A sample of my data table with headers looks like this:
Product | Notice | Assigned | Complete | In Office | In Accounting
1 | 5/5/13 | 5/7/13 | 5/9/13 | 5/10/13 | 5/11/13
2 | 5/5/13 | 5/6/13 | 5/8/13 | 5/9/13 | 5/10/13
3 | 5/6/13 | 5/9/13 | 5/10/13 | 5/10/13 | 5/10/13
4 | 5/4/13 | 5/5/13 | 5/7/13 | 5/8/13 | 5/9/13
5 | 5/7/13 | 5/8/13 | 5/10/13 | 5/11/13 | 5/11/13
If my output table were to contain a set of dates in the first column with the statuses as headers, I need a count of how many rows were at the given status and had not yet transitioned to the next status so that in the Notice column, I'd have a count of rows where the Notice Date was <= X AND where the Assigned, Complete, In Office, In Accounting are all greater than X.
I've used a Sum(if(frequency(if statement to get me REALLY close but I feel like I need to have an AND statement within the second IF like this =SUM(IF(FREQUENCY(IF(AND
Here's what I have that won't work:
=SUM(IF(FREQUENCY(IF(AND(Table1[Assigned]<=A279,Table1[[Complete]:[In Accounting]]<=A279),ROW(Table1[[Complete]:[In Accounting]])),ROW(Table1[[Complete]:[In Accounting]]))>0,1))
If I take the "AND" portion out, this works fine except I need it to ONLY count rows where the given status actually has a date so if an "Assigned" date is empty, I don't want that row to be counted for the Assigned column.
Here's an example of what I'd expect to see in the results. I've listed the count in the each column as well as the corresponding product numbers in parenthesis. The corresponding product numbers are for reference only and won't actually be in the result table.
Date | Notice | Assigned | Complete
5/6 | 2 (1,3) | 2 (2,4) | 0
5/7 | 2 (3,5) | 2 (1,2) | 1 (4)
5/8 | 1 (3) | 2 (1,5) | 1 (2)
OK, assuming you have the original data in A1:F6 then with 2nd table headers in B9:D9 and row labels in A10:A12 then you can use this "array formula" in B10
=SUM((B$2:B$6<=$A10)*(MMULT((C$2:$F$6>$A10)+(C$2:$F$6=""),TRANSPOSE(COLUMN(C$2:$F$6)^0))=COLUMNS(C$2:$F$6)))
confirmed with CTRL+SHIFT+ENTER and copied down and across (see screenshot below)
As you can see the results are as per your requirement. If you replace dates with blanks it will still work
MMULTis a way to get a single value from each row even when you are looking at multiple columns.
I used cell references because I think that's easier, especially when copying the formula across and having a reducing range.......but you can use structured references if you want
Have you tried using COUNTIFS to count based on multiple criteria. It is fairly well documented here: http://office.microsoft.com/en-us/excel-help/countifs-function-HA010047494.aspx (2007+ only)
Basically, you use it like
=COUNTIFS(first_range_to_check, value_you_want_in_first_range, ...)
where the ... represents as many pairs as you want (up to 127 total pairs), note the conditions are AND connection so if you have two pairs, the first pair AND the second pair must return true for that row to count.

MS Excel - finding the first row after a certain date

Say I have a spreadsheet with the following, and for convenience say all of this starts from cell A1.
---------------------------------------
| Date | Item | Account |
---------------------------------------
| 01/09/2011 | Testing 1 | USD |
| 03/09/2011 | Testing 2 | USD |
| 11/09/2011 | Testing 3 | USD |
| 20/10/2011 | Testing 4 | JD |
| 22/10/2011 | Testing 5 | JD |
| 25/10/2011 | Testing 6 | USD |
| 03/11/2011 | Testing 7 | USD |
| 05/11/2011 | Testing 8 | JD |
---------------------------------------
Now, I want to run a report for a month, starting on 1/10/2011 and ending on 31/10/2011. I need to find the first row on or after the starting date, and then get every subsequent row until the end date. If I can figure out how to get the row reference for the first and end dates, then I can figure out the rows in between (obviously!).
I have only been able do these sorts of matches on exact matches ie. no idea how to do 'greater/less than' matches.
How would I go about matching on both the date and the account columns?
Needless to say, this needs to be in a formula.
=match(date(2011,10,1),a2:a9,1)+1
=match(date(2011,10,31),a2:a9,1)
First formula shows row for the first record for October, second formula for the last day. Data must be sorted in ascending order.
Use the following Array Formula for finding the Row containing the earliest date, which is equal to or greater than the date mentioned in cell C1 (in your case this is 1 October).
=MATCH(MIN(IF($A$1:$A$30>=C1,1,9999)*$A$1:$A$30),$A$1:$A$30,0)
Date list is in cells A1 to A30. Change the references as required.
Data need not be sorted in ascending or descending order.
Use the following Array Formula for finding the Row containing the latest date which is equal to or less than the date mentioned in cell D1 (in your case this is 31 October). Data need not be sorted in ascending or descending order.
=MATCH(MAX(IF($A$1:$A$30<=D1,1,0)*$A$1:$A$30),$A$1:$A$30,0)
If you want the earliest and latest dates, use the following Array Formulas.
=MIN(IF($A$1:$A$30>=C1,1,9999)*$A$1:$A$30)
=MAX(IF($A$1:$A$30<=D1,1,0)*$A$1:$A$30)
All the formulas used above are Array Formulas. To enter an array formula, use Control+Shift+Enter instead of Enter.
Vijaykumar Shetye, Goa, India
I would recommend using a pivot table for this. Look at the second link on in the "Excel Templates - Pivot Table" section on this page on the Contextures site.

Excel Formulas: Show total based on date entry

I've got a spreadsheet with two columns that represent the number of processed records, and the date the records were processed. In some cases, the records can be processed in multiple batches, so the document looks something like this:
33 4/1/2009
22 4/1/2009
12 4/2/2009
13 4/4/2009
36 4/4/2009
I'm trying to add a new set of columns that contain a date, and shows the total number of records for that date, automagically:
4/1/2009 55
4/2/2009 12
4/3/2009 0
4/4/2009 49
I know how to do this algorithmically, and I could probably manipulate the spreadsheet outside of Excel, but I'm trying to do this in the live spreadsheet, and am a bit bewildered as to how to pull it off.
Any ideas?
Thanks!
IVR Avenger
Will the SUMIF function work for you? SUMIF([range],[criteria],[sum_range]) I think you could set range = the set of cells containing dates in your first listing, criteria would be the cell containing the date in the second listing, and sum_range would be the counts in the first column of your first listing.
I would suggest using a Pivot Table. Put the dates into the row area and 'sum of' records in the data area. Nothing in the columns area.
A pivot table will be more dynamic than a formula solution because it will only show you dates that exist.
Assuming your dates are in column B and the numbers to be accumulated are in A, you could try something like this:
| A | B | C D
1 | 33 | 4/1/2009 | =MIN(B:B) | {=SUM(IF(B1:B5=C1,A1:A5,0))} |
2 | 22 | 4/1/2009 | =C1+1 | {=SUM(IF(B1:B5=C2,A1:A5,0))} |
3 | 12 | 4/2/2009 | =C2+1 | {=SUM(IF(B1:B5=C3,A1:A5,0))} |
4 | 13 | 4/4/2009 | =C3+1 | {=SUM(IF(B1:B5=C4,A1:A5,0))} |
5 | 36 | 4/4/2009 | =C4+1 | {=SUM(IF(B1:B5=C5,A1:A5,0))} |
Note the {} which signifies an array formula (input using Control-Shift-Enter) for any non-trivial amount of data it's heaps faster than SUMIF().
I'd be inclined to define dynamic names for the A1:A5 and B1:B5 parts, something like
=OFFSET(A1,0,0,COUNT(A:A),1)
so that I didn't have to keep fixing up my formulae.
There's still a manual element: adding new rows for extra dates, for example - that might be a good place for a little VBA. Alternatively, if you can get away with showing, for example, the last 90 days' totals, then you could fix the number of rows used.

Resources