I am trying to create an IF statement formula in excel that converts minutes to days and hours depending on the amount. Then rounds the value to 1 or 2 decimal points and adds the descriptive text (days, hours, etc) to the end
I have tried the following which converts and adds text but does not round:
=IF(L15>=1440, CONVERT(L15,"min","day") & CONCATENATE(L15," days"),
IF(L15>=60, CONVERT(L15,"min","hr") & CONCATENATE(L15," hours"),
IF(L15<=59, CONVERT(L15,"min","min") & CONCATENATE(L15," mins"))))
I would adjust your formula as follows and based on you wanting to round the final number
=IF(L15>=1440,ROUND(L15/1440,2)&" days",IF(L15>=60,ROUND(L15/60,2)&" hours",ROUND(L15,2)&" minutes"))
the ,2 in the ROUND function tell excel how many decimal places to calculate to. if format is set to general, trailing 0s will not be displayed. If you only want 1 decimal calculation then change the ,2 to ,1.
Related
There are 2 text boxes called #IMPORTOORARIO and #ANTICIPO.
The user writes in the first one '45,56', and in the second one '45'.
I want to cast the first string to decimal and the second one to tinyint.
No matter what I try: if the cast succeds, I end up with '45,56' casted to 4,00 and '45' to 4.
Just 4. Not 4,00.
Here is part of the store procedure I am using:
INSERT INTO TableName
VALUES
(
try_convert(decimal(6, 2),#IMPORTOORARIO),
try_convert(tinyint,#ANTICIPO)
)
I attach a screenshot to show the problem.
You will see more text boxes and table fields but the problem is always the same, just focus on #IMPORTOORARIO and #ANTICIPO.
#IMPORTOORARIO = number 3. #ANTICIPO = number 4
Info: the maximum number I am going to store in the database is decimal(9, 2).
So something like: 123456,78
So 6 numbers before the comma and 2 after the comma.
To solve the problem, I tried to use CAST, CONVERT, TRY_CONVERT, and something I did not understand with REPLACE:
Select try_convert(numeric(6, 2),replace('25,12', ',', '.'))
I want to find the minimum number with given conditions(is writer and is under probation), the below code works if D contains numbers, but how do I do it if the number is a part of a string, like a fraction for example? Like how do I use this formula if numbers in D look like "1/8", "31/688", "21/33", etc?
=MINIFS(D3:D1007, A3:A1007, "Writer", C3:C1007, "Probation")
I already have another formula that I use that calculates a decimal value given the fraction, If the fraction is in cell D21 then it would look like this:
=left(D21,find("/",D21)-1)/(right(D21,len(D21)-find("/",D21)))
but how do I apply this kind of formula in a minif/maxif?
I have attached a picture to show what I mean, what I'm trying to do is to put a formula in the passed/total column of package stats(probation), and it will get the lowest passed/total value out of the ones with that package name and importance level. as you can see, the entire writer package's pass rate is 5/8 because the lowest pass rate out of the writer package 5/8 is the lowest pass rate out people with package=writers and importance = probation. But at the moment I have to enter the 5/8s manually, I want it to be able to get it automatically using the formula I'm trying to figure out above.
try:
=ARRAYFORMULA(MIN(IF((A3:A="writer")*(C3:C="probation"),
IFERROR(REGEXEXTRACT(D3:D, "\d+")/REGEXEXTRACT(D3:D, "/(\d+)"), D3:D), )))
or to return fraction:
=ARRAYFORMULA(VLOOKUP(MIN(IF((A3:A="writer")*(C3:C="probation"),
IFERROR(REGEXEXTRACT(D3:D, "\d+")/REGEXEXTRACT(D3:D, "/(\d+)"), D3:D), )),
{IF((A3:A="writer")*(C3:C="probation"),
IFERROR(REGEXEXTRACT(D3:D, "\d+")/REGEXEXTRACT(D3:D, "/(\d+)"), D3:D), ), D3:D}, 2, 0))
also make sure fractions are formatted as plain text not date
I'm am exploring methods of giving scores to different datapoints within a dataset. These points come from a mix of numbers and text string attributes looking for certain characteristics, e.g. if Col. A contains more than X number of "|", then give it a 1. If not, it gets a 0 for that category. I also have some that give the point when the value is >X.
I have been trying to do this with =IF, for example, =IF([sheet] = [Text], "1","0").
I can get it to give me 1 or 0, but I am unable to get a point total with sum.
I have tried changing the formatting of the text to both "number", "plain text", and have left it as automatic, but I can't get it to sum. Thoughts? Is there maybe a better way to do this?
FWIW - I'm trying to score based on about 12 factors.
Best,
Alex
The issue here might be that you're having the cell evaluate to either the string "0" or the string "1" rather than the number 0 or the number 1. That would explain why you're seeing the right things but the math isn't coming out right - the cell contents look like numbers, but they're really text, which the summation would then ignore.
One option would be to drop the quotation marks and write something like this:
=IF(condition, 1, 0)
This has the condition evaluate to 1 if it's true and 0 if it's false.
Alternatively, you could write something like this:
=(condition) * 1
This will take the boolean TRUE or FALSE returned by condition and convert it to either the numeric value 1 (true) or the numeric value 0 (false).
I have a float-type-field which contains big number (more than 20 digits). Then I want to convert it to varchar, without rounding. I tried several queries, but nothing.
Here is for example :
SELECT CAST(A AS VARCHAR(25)) AS B
, TRIM(TRAILING '.' FROM CAST(CAST(A AS DECIMAL(25)) AS VARCHAR(25))) AS C
, TRIM(LEADING '0' FROM CAST(CAST(A AS FORMAT '9(25)') AS VARCHAR(25))) AS D
FROM ( SELECT CAST(79999999999999999999.000 AS FLOAT) A ) t0
And the result
B : 8.00000000000000E 019
C : 80000000000000000000
D : 80000000000000000000
I expect to get '79999999999999999999'
Any advises are appreciated.
When you run SELECT CAST(79999999999999999999.000 AS FLOAT) you get 80.000.000.000.000.000.000,000 as result. The precision of a FLOAT is 15 to 16 digits, your input has 20 significant digits, so it's already rounded during the typecast.
As you can't store numbers like this in a Teradata FLOAT the question is: Where's this "float-type-field" coming from? Oracle?
Is there a know maximum n for fractional digits? Then CASTing as DECIMAL(38,n) might be ok.
What's your TD release? 14 introduced the NUMBER datatype to easy porting from Oracle.
NUMBER might be used as a "float-type-field" with approx. 38 digits.
I have an unbalanced panel data set (countries and years). For simplicity let's say I have one variable, x, that I am measuring. The panel data sorted first by country (a 3-digit numeric country-code) and then by year. I would like to write a .do file that generates a new variable, z_x, containing the standardized values of the variable x. The variables should be standardized by subtracting the mean from the preceding (exclusive) m time periods, and then dividing by the standard deviation from those same time periods. If this is not possible, return a missing value.
Currently, the code I am using to accomplish this is the following (edited now for clarity)
xtset weocountrycode year
sort weocountrycode year
local win_len = 5 // Defining rolling window length.
quietly: rolling sd_x=r(sd) mean_x=r(mean), window(`win_len') saving(stats_x, replace): sum x
use stats_x, clear
rename end year
save, replace
use all_data_PROCESSED_FINAL.dta, clear
quietly: merge 1:1 (weocountrycode year) using stats_x
replace sd_x = . if `x'[_n-`win_len'+1] == . | weocountrycode[_n-`win_len'+1] != weocountrycode[_n] // This and next line are for deleting values that rolling calculates when I actually want missing values.
replace mean_`x' = . if `x'[_n-`win_len'+1] == . | weocountrycode[_n-`win_len'+1] != weocountrycode[_n]
gen z_`x' = (`x' - mean_`x'[_n-1])/sd_`x'[_n-1] // calculate z-score
UPDATE:
My struggle with rolling is that when rolling is set up to use a window length 5 rolling mean, it automatically does window length 1,2,3,4 means for the first, second, third and fourth entries (when there are not 5 preceding entries available to average out). In fact, it does this in general - if the first non-missing value is on entry 5, it will do a length 1 rolling average on entry 5, length 2 rolling average on entry 6, ..... and then finally start doing length 5 moving averages on entry 9. My issue is that I do not want this, so I would like to avoid performing these calculations. Until now, I have only been able to figure out how to delete them after they are done, which is both inefficient and bothersome.
I tried adding an if clause to the -rolling- statement:
quietly: rolling sd_x=r(sd) mean_x=r(mean) if x[_n-`win_len'+1] != . & weocountrycode[_n-`win_len'+1] != weocountrycode[_n], window(`win_len') saving(stats_x, replace): sum x
But it did not fix the problem and the output is "weird" in the sense that
1) If `win_len' is equal to, say, 10, there are 15 missing values in the resulting z_x variable, instead of 9.
2) Even though there are "extra" missing values in z_x, the observations still start out as window length 1 means, then window length 2 means, etc. which makes no sense to me.
Which leads me to believe I fundamentally don't understand 1) what -rolling- is doing and 2) how an if clause works in the context of -rolling-.
Does this help?
Thanks!
I'm not sure I understand completely but I'll try to answer based on what I think your problem is, and based on a comment by #NickCox.
You say:
... when rolling is set up to use a window length 5 rolling mean...
if the first non-missing value is
on entry 5, it will do a length 1 rolling average on entry 5, length 2
rolling average on entry 6, ...
This is expected. help rolling states:
The window size refers to calendar periods, not the number of
observations. If there
are missing data (for example, because of weekends), the actual number of observations used by command may be less than
window(#).
It's not actually doing a "length 1 rolling average", but I get to that later.
Below some examples to see what rolling does:
clear all
set more off
*-------------------------- example data -----------------------------
set obs 92
gen dat = _n - 1
format dat %tq
egen seq = fill(1 1 1 1 2 2 2 2)
tsset dat
tempfile main
save "`main'"
list in 1/12, separator(4)
*------------------- Example 1. None missing ------------------------
rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)
*------- Example 2. All but one value, missing in first window ------
use "`main'", clear
replace seq = . in 1/3
list in 1/8
rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)
*------------- Example 3. All missing in first window --------------
use "`main'", clear
replace seq = . in 1/4
list in 1/8
rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)
Note I use the stepsize option to make things much easier to follow. Because the date variable is in quarters, I set windowsize(4) and stepsize(4) so rolling is just computing averages by year. I hope that's easy to see.
Example 1 does as expected. No problem here.
Example 2 on the other hand, should be more interesting for you. We've said that what matters are calendar periods, so the mean is computed for the whole year (four quarters), even though it contains missings. There are three missings and one non-missing. summarize is computing the mean over the whole year, but summarize ignores missings, so it just outputs the mean of non-missings, which in this case is just one value.
Example 3 has missings for all four quarters of the year. Therefore, summarize outputs . (missing).
Your problem, as I understand it, is that when you face a situation like Example 2, you'd like the output to be missing. This is where I think Nick Cox's advice comes in. You could try something like:
rolling mean=r(mean) N=r(N), window(4) stepsize(4) clear: summarize seq, detail
replace mean = . if N != 4
list in 1/12, separator(0)
This says: if the number of non-missings for the window (r(N), also computed by summarize), is not the same as the window size, then replace it with missing.