Convert words to number in Google Sheets - google-sheets

I have an API connected to my Sheets where I receive data in words instead of numbers.
Example, Ratings data is recieved as "Five" instead of numeric "5".
How do I convert the recieved data into numeric values?
I have tried =value() and it doesn't seem to be working.

Using Mike's solution below you can create a custom function in Google Apps Scripts. But you can also achieve this by using VLOOKUP
You can simply create a sheet which has all the possible ratings in Text and numeric values. Then you can use VLOOKUP to convert the data from actual sheet to numbers
Refer to the following sheet.
=ArrayFormula(VLOOKUP(A4:A14,'Text to Num'!A1:B9,2,FALSE))
Note: ArrayFormula is used so that you don't have to copy paste formula in multiple cells.

1- Try this for one single number
function toNum(txt){
var num = ["zero", "one", "two", "three", "four", "five","six", "seven", "eight", "nine"]
return num.indexOf(txt.toLowerCase())
}
2- You can also use a standalone formula (following Gangula's idea)
=MATCH(A1,{"zero"; "one"; "two"; "three"; "four"; "five";"six"; "seven"; "eight"; "nine"},0)-1

Related

Sum multiple arrays into one

Been trying to tackle this issue for a couple days and without much progress.
I have a multiple date filter (or a query) which filters a date array: i.e. array of dates from 12.2020 to 01.2022 and multiple filters range (01.2021-02.2021, 05.2021-09.2021).
This process filters the dates and produces multiple filtered arrays. The pic of how it looks is attached.
The formula used to produce arrays =ARRAYFORMULA(IF((($F$5:$S$5>=QUERY($B$3:$D$4;"select C where B = "&D8&""))*(F$5:$S$5<=ARRAYFORMULA(FILTER($D$3:$D$4;$B$3:$B$4=$D$8))));1;0))
As you can see, it generate multiple arrays, depending on the amount of filters applied.
My question is following is it possible to sum these arrays into one with one formula? So I would get 1 array instead of multiple.
EDIT 1: Link for clarity
Screenshot of google sheet
Try
=transpose(mmult(arrayformula(VALUE(transpose( ARRAYFORMULA(IF((($F$5:$S$5>=QUERY($B$3:$D$4,"select C where B = "&D8&""))*(F$5:$S$5<=ARRAYFORMULA(FILTER($D$3:$D$4,$B$3:$B$4=$D$8)))),1,0)) ))),sequence( 2,1,1,0)))
Explanation
I encapsulate your formula and your result in a MMULT formula to get the sum of each column
=transpose(mmult(arrayformula(VALUE(transpose(F8:S9))),sequence(2,1,1,0)))
Another option:
=ARRAYFORMULA(MMULT(COLUMN($B$3:$D$5)^0,(($F$5:$S$5>=QUERY($B$3:$D$5,"select C where B = "&D8&""))*(F$5:$S$5<=ARRAYFORMULA(FILTER($D$3:$D$5,$B$3:$B$5=$D$8))))))

How to create arrayformula sequence number separated by comma in google sheets

How to create arrayformula sequence number separated by comma in google spreadsheets
expected results is in column B
A
B
5
1,2,3,4,5
2
1,2
3
1,2,3
How about the following sample formula?
Sample formula:
=JOIN(",",ARRAYFORMULA(ROW(INDIRECT("A1:A"&A1))))
When you use this formula, please put this to a cell "B1" and drag down it.
The flow of this formula is as follows.
Create a1Notation of cells using "A1:A"&A1 using INDIRECT.
Retrieve row numbers from the a1Notation using ROW.
Join the row numbers with , using JOIN.
Result:
Note:
When you want to put all result values using one formula, unfortunately, I couldn't find the formula using the built-in functions. In that case, I would like to propose to a custom function as follows. When you use this, please copy and paste the following script to the script editor of Spreadsheet.
And, please put a formula of =SAMPLE(A1:A) to a cell "B1". By this, the result values are put to the column "B" using the values of column "A".
const SAMPLE = v => v.map(([e]) => e && !isNaN(e) ? [...Array(e)].map((_, i) => i + 1).join(",") : "");
References:
INDIRECT
ROW
JOIN
Custom Functions in Google Sheets
You can use TEXTJOIN() with SEQUENCE() function.
=TEXTJOIN(",",TRUE,SEQUENCE(A1))
You can also use this functions in desktop Excel365

Finding duplicates and fixing them

I was wondering if there was a way to find duplicate values in Google sheets regardless of formatting errors and also fix them.
For example, list one is literally the same as list two. But in sheets the duplicates aint picked up.
List One:
Alcatel
Apple
Benq-Siemens
Blackberry
Google
HTC
Huawei
LG
Manufacturer
Motorola
Nokia
One Plus
Samsung
Sony-Ericcson
List Two:
Manufacturer
Alcatel
apple
benqsiemens
Blackberry
Google
hTC
Huawei
lg
Manufacturer
Motorola
Nokia
One Plus
Samsung
Sonyericcson
Please note in the List Two the only ones with errors as in formatting errors are apple,benqsiemens,hTC,lg,Sonyericsson.
How do I do it so that the two list have all duplicates selected despite any formatting errors and also fix them?
Thanks
Use this formula
=ArrayFormula(IFERROR(IF(REGEXMATCH(PROPER(C2:C),REGEXEXTRACT(PROPER(B2:B),"\w+")),B2:B,"MANUAL FIX")))
MANUAL FIX you have when formula can not fix it.
You have to first fix C and then formula will work.
I think you can check out example Example 4. Compare two Google Sheets for differences to compare the two sheets https://www.ablebits.com/office-addins-blog/2019/04/30/google-sheets-compare-two-sheets-columns/
Here is a sample code on how to fix the format of your list two based on list one:
function fixDuplicates() {
var listOne = 'Sheet2!A2:A';
var listTwo = 'Sheet2!B2:B';
var sheet = SpreadsheetApp.getActiveSheet();
var listOneVal = sheet.getRange(listOne).getDisplayValues().flat().filter(String);
var listTwoRange = sheet.getRange(listTwo);
var listTwoVal= listTwoRange.getDisplayValues().flat().filter(String);
//clone list two value
var tmpListTwo = [...listTwoVal];
//Update Temp List Two Values,remove spaces, special characters and set to uppercase
tmpListTwo.forEach((val,index) => {
tmpListTwo[index] = val.replace(/[^a-zA-Z0-9]/g,"").toUpperCase();
});
//Find list one value in temp list two
listOneVal.forEach(val =>{
//Remove spaces, special characters and set to uppercase
var tmp = val.replace(/[^a-zA-Z0-9]/g,"").toUpperCase();
var index = tmpListTwo.indexOf(tmp);
if(index != -1){
Logger.log("Finding: "+listTwoVal[index]);
var textFinder = listTwoRange.createTextFinder(listTwoVal[index]);
var firstOccurrence = textFinder.findNext();
if(firstOccurrence!=null){
//duplicate found, fix the duplicate format. set cell value based on list one value
firstOccurrence.setValue(val);
Logger.log("Value set to: "+val);
}
}
});
}
What it does?
Define your list one and two range in A1Notation (Including the sheet name)
Get the values of your list one and two, change 2-d array to 1-d array using array.flat() and remove empty-cell values using array.filter()
Clone your list two array. Format your temporary list two array by removing all special characters, spaces and set it to upper case.
Loop all your list one value, transform your current list one value by also removing special characters, spaces and set to upper case. Get the index of list one value in your temporary list two array.
Once we determined the duplicates in list two, we will use Range.createTextFinder(findText) to search for the duplicate's range. Then set its value using Range.setValue(value) using your list one value.
Output:
See your original list two value in column F
After running the code, it was transformed to the one in column B
See Cell C1, on how to get the duplicates in column B using the formula: =Filter(B2:B,MATCH(A2:A,B2:B,0))

How to combine data from two google sheet and exclude the empty row?

Hi everyone,
I have 2 google sheets with data as shown in the screenshot above. For the first google sheet, the empty row are row 3 & row 7. For the second google sheet, the empty row are row 2, row 7 and row 10. I want to combine these two google sheets in a master google sheet. This is what I used to combine the data and the result that I get:
=QUERY({IMPORTRANGE("1BT3KLMGoE3FMaiW8G1ig6GRTyaJnYcskSaIeki7m-gs","Sheet1!A1:J100"),IMPORTRANGE("1gW5rEiinQe-PaqvFH890ZXXx7YnSVtmUghhpTl7lGng","Sheet1!A1:J100")},"where Col2 is not null")
As you can see, the data from second google sheet start from Column K and row 3 data is missing. I want to start the data from second google sheet in row 9 instead of Column K. May I know what I did wrong in the QUERY and IMPORTRANGE and how to avoid missing the data from second google sheet (row 3 data)?
Hope to get some helps and advices, thank you.
Issue:
As per kishkin's comment,
Try replacing comma , before the 2nd IMPORTRANGE with semi-colon
Formula:
=QUERY({IMPORTRANGE("1BT3KLMGoE3FMaiW8G1ig6GRTyaJnYcskSaIeki7m-gs","Sheet1!A1:J100");IMPORTRANGE("1gW5rEiinQe-PaqvFH890ZXXx7YnSVtmUghhpTl7lGng","Sheet1!A1:J100")},"where Col2 is not null")
Delimiter used is , instead of ;. I assume you are located most likely in Europe and that is the reason of the issue. See reason below.
Reason:
Locations using decimal points:
For locations using periods (or points or dots or whatever you call them) to denote decimal separators (most non-European countries including US, UK, Australia), the syntax will follow this structure:
Decimals will be denoted by a decimal point (a period)
Arguments in formulas separated by a comma
Horizontal data in curly-brace arrays separated by a comma
Locations using decimal commas:
For locations using commas to denote decimal separators (most European countries), the syntax will follow this structure:
Decimals will be denoted by a comma
Arguments in formulas separated by a semi-colon
Horizontal data in curly-brace arrays separated by a back-slash
Output:
Reference:
Sheets Location

Using arrayformula with countif only up to a certain row

I have a sheet with a column of data where the entry is one of two strings, for simplicity's sake we'll say "A" and "B". I want another column of calculated data which is the differential between the number of "A"s and the number of "B"s up to that point, so just a countif()-countif() with the range increasing by one row. I can do this using =countif(A$2:A2, "A") - countif(A$2:A2, "B"), but it means I have to keep filling that equation down to cover any newly entered data, so I figured an array formula would be the best option to not have to do that. However when I try to use =arrayformula(countif(A$2:A, "A") - countif(A$2:A, "B")), it only populates a single cell with the difference counting the entire column. Is there a way to use an array formula so that it increases the range by one row for every row it populates?
=ARRAYFORMULA("A2:A"&ROW(A2:A))
This will give a dynamic string for the right range, which in theory, you should be able to wrap with INDIRECT, to plug into COUNTIF.
But COUNTIF only works in some circumstances with ARRAY FORMULA
Unfortunately, AFAIK, only if you use COUNTIF like this:
=ARRAYFORMULA(COUNTIF(A1:A100,A1:A100))
will it work as an array formula. Note how both the ranges in the arguments are the same.
MMULT
There may be a way along these lines with MMULT:
=ARRAYFORMULA(
MMULT(
(A2:A100 = TRANSPOSE(A2:A100)) * (ROW(A2:A100) >= TRANSPOSE(ROW(A2:A100))),
SIGN(ROW(A2:A100))
)
)
But I couldn't get that to work because I am not 100% sure on how to use MMULT in this way, but I have seen that type of solution elsewhere.
An Apps Script Workaround
As you have seen, what you want to achieve with sheet functions quickly gets very complicated. If you wanted to use more letters or different rules, it would get tough to maintain. Apps Script can make these things much simpler.
So here is a custom Apps Script function:
function myFunction() {
// Initializing
let file = SpreadsheetApp.getActive();
let sheet = file.getSheetByName("Sheet1");
var lastRow = sheet.getLastRow();
// This is the range of the As and Bs
let range = sheet.getRange(2,1, parseInt(lastRow) - 1,1)
let rows = range.getValues();
// Creating an object to keep track of the count
let tracker = {}
// This will be the output column
let newCol = []
rows.forEach(row => {
tracker[row[0]] += 1
// Adding a row to the output
newCol.push([tracker.A - tracker.B])
})
return newCol
}
Paste that into the script editor and you can use it like this:
Demo:
You can change the name of the function in the script editor according to what you need it for, just remember to call it with that name from the sheet.
References
Main Page
Sheets Guide
Tutorials
Sheets Reference
INDIRECT
MMULT
try:
=ARRAYFORMULA(
COUNTIFS(A2:A, A2:A, A2:A, "A", ROW(A2:A), "<="&ROW(A2:A))-
COUNTIFS(A2:A, A2:A, A2:A, "B", ROW(A2:A), "<="&ROW(A2:A)))
Alternatively, you may this IF statement:
=ARRAYFORMULA(IF(K2:K<>"",K2:K*B294,""))
Results (Above formula is applied on L2 row onwards):
Source: https://blog.sheetgo.com/google-sheets-formulas/arrayformula-google-sheets/

Resources