Calculate Alpha number

Hello ,
I have the following reprex and add column coding :

INPUT:
df <- tibble::tribble(
~seq, ~date, ~sales,
1, "3/01/2017", 40,
2, "4/01/2017", 2,
3, "5/01/2017", 2,
4, "6/01/2017", 2,
5, "7/01/2017", 30,
6, "8/01/2017", 2,
7, "1/02/2017", 9,
8, "2/02/2017", 5,
9, "3/02/2017", 65,
10, "4/02/2017", 3,
11, "5/02/2017", 65
)
add_column(df, z = -1:1, w = 0)
add_column(df, z = 0, w = 0)

OUTPUT
seq date sales z w

1 1 3/01/2017 40 0 0
2 2 4/01/2017 2 0 0
3 3 5/01/2017 2 0 0
4 4 6/01/2017 2 0 0
5 5 7/01/2017 30 0 0
6 6 8/01/2017 2 0 0
7 7 1/02/2017 9 0 0
8 8 2/02/2017 5 0 0
9 9 3/02/2017 65 0 0
10 10 4/02/2017 3 0 0
11 11 5/02/2017 65 0 0

QUESTION
I need to fill in column Z a calculation for the Alpha per line,based on previous sales.So, I need to start at the 5th sequence ( qty '30').
How do I calculate the Alpha number in column Z per line,starting at line 5? what would the coding be?
(5 5 7/01/2017 30 0 0)

cheers

Not quite a reprex. That would be a copy, paste and run, meaning that all of the necessary data ✓ functions :x: and libraries ✓ needed are included.

Yes, and best between a pair of triple backticks, like this:

```
<--- libraries needed
<--- data needed
<--- code
# output
```

with non-code commented out as shown.

What do you mean by 'alpha', @ron4?

1 Like

Hi David.I have followed Technocrats advise and started a R course.So there's a lot to learn I've noticed. I am sincerely happy with all the help i can get.
I know how to import a matrix.But I also learned from another user how to .make a tibble..

Can you show me what the code I need to calculate Alpha ?To explain what I mean with Alpha :Its the confidence level of the baseline. i found some explaining code on the following internet site: https://www.wessa.net/rwasp_cronbach.wasp

I would need parts of that code re-written ,so it can be connected to my data and shows in the extra added Z column.
If i have that, I can add it myself into my script. :-),I 'm learning.
cheers
....

1 Like

Have you installed the package and read the doc?
https://personality-project.org/r/html/alpha.html

This journey is doubly difficult: statistics and learning R. Again, you'll get better help with a reprex, which looks like this

library(psy)
data(expsy)
cronbach(cbind(expsy[,c(1,3:10)],-1*expsy[,2]))
#> $sample.size
#> [1] 27
#> 
#> $number.of.items
#> [1] 10
#> 
#> $alpha
#> [1] 0.3752657

Created on 2020-03-21 by the reprex package (v0.3.0)

How to read this?

  1. There's package for that. I found psy with the R google front end. And psy was the first hit searching for cronbach, mentioned in the link, even the name of the link.
  2. The package has a function for cronbach
  3. It produces alpha from its argument.

The take-away: don't reinvent the wheel

The second is that almost all of R isn't really programming. It's school algebra f(x) = y.

For its functional orientation to work it's crucial to two understand two concepts: x and y. The first is the argument, and the second is the value, or result.

The argument is an object, like everything else in R. It can be as simple as an integer or as a convoluted as, well, you don't want to know, yet.

cronbach() takes as its argument

v1
n*p matrix or dataframe, n subjects and p items

It's value is what the reprex shows, which can be confirmed by looking at the structure

str(cronbach(cbind(expsy[,c(1,3:10)],-1*expsy[,2])))
List of 3
 $ sample.size    : int 27
 $ number.of.items: int 10
 $ alpha          : num 0.375

Also, not to be overlooked is the description at the top of the help(cronbach) page

Computes the Cronbach's reliability coefficient alpha. This coefficient may be applied to a series of items destinated to be aggregated in a single score. It estimates reliability in the framework of the domain sampling model.

That's a lot to unpack. It's not something that is easily understood without knowing what to do with alpha, but that's a question for another day.

1 Like

Hi, Thank you for this very helpful info.
I did not have psy installed.I have now.I ran the code and indeed, it gave me the correct C.Alpha.

so,I have a data set imported ,names Sales1 ,in which I want to add the new column to existing data sales and I want to name the added column 'CAlpha' .

my output looks like this now that i use a dataset.

sales1

A tibble: 341 x 2

Date sales

1 03-01-2017 40
2 04-01-2017 2
3 05-01-2017 2
4 06-01-2017 2
5 07-01-2017 30
6 08-01-2017 2
7 01-02-2017 9
8 02-02-2017 5
9 03-02-2017 65
10 04-02-2017 3

... with 331 more row

So now i need to add that Alpha calculation behind every item and calculate a rolling Alpha based on the previous 2 items.

code would be ?
colnames(sales1) <- c("Alpha")
cronbach(cbind(expsy[,c(1,3:2)],-1*expsy[,2]))

where to put the Alpha calculation in the code?
cheers

Hi Nir, i didnt have the package.Now i have.Thanks :slight_smile:
I also asked Technocrat,
How do in add a column with a Chronbachs Alpha behind every item in my matrix.
He info'd me on the formula for all items ,but i need it per item in an added column in that same matrix.

My output would look like this:

Date sales alpha
03-01-2017 40
04-01-2017 2 0.0999
05-01-2017 2 0.1461
06-01-2017 2 0.1897
07-01-2017 30 0.0569
08-01-2017 2 0.1304
01-02-2017 9 0.0839
02-02-2017 5 0.0244
03-02-2017 65 0.1063
04-02-2017 3 0.0911
05-02-2017 65 0.0591
06-02-2017 1 0.0668
07-02-2017 11 0.074
08-02-2017 9 0.0859
01-03-2017 21 0.0943
02-03-2017 65 0.1425
03-03-2017 5 0.124
04-03-2017 10 0.1174
05-03-2017 40 0.1164

I have a doubt that you understood and ran the function correctly, as this that you wrote is not your sales data, but example psy data. expsy , right ?

1 Like

The expsy data set is simply to illustrate use of the cronbach()

Recall that the argument to the function is an n x p matrix. What happens if you give it an integer?

library(psy)
# create a 1 x 1 matrix
m <- matrix(1)
# find alpha
cronbach(m)
#> $sample.size
#> [1] 1
#> 
#> $number.of.items
#> [1] 1
#> 
#> $alpha
#> [1] NA

Created on 2020-03-22 by the reprex package (v0.3.0)

Hi, correct, i found this code in a leaning book
what would need to correct on that code? would it need to be:

cronbach(cbind(sales1[,c(1,3:2)],-1*sales1[,2]))

my R says: object 'sales1' not found
cheers

Hi, thanks. so the code should be ? : cronbach(cbind(sales1[,c(1,3:2)],-1*sales1[,2]))
My imported file name is sales1
cheers

  1. if you don't see sales1 in ls(), then neither does your code
  2. The data in the question was all integers, which cannot be subset

My recommendation is to come up to speed in R basics before trying to apply code mechanically. A good place to start is with completing all the exercises in R for Data Science

The reprex will take care of the quoting and commenting out any output, so it's truly all cut-and-paste. First install it

install.packages("reprex")

and then use the RStudio addins pop-up selector and scroll or search. Highlight the code and apply the addin, which will copy to the clipboard

The big problem is usually data. The fix

  1. use
dput(my_data)

and cut-and paste the output and paste

dput(my_data) # cut and past the output into the reprex

A direct to clipboard alternative in lieu of running dput is this function that I ripped off somewhere for which I apologize to the author

require(clipr)
#> Loading required package: clipr
#> Welcome to clipr. See ?write_clip for advisories on writing to the clipboard in R.
require(magrittr)
#> Loading required package: magrittr
require(stringr)
#> Loading required package: stringr

specimen <- function(x)
  deparse(x) %>%
  str_c(collapse = '') %>%
  str_replace_all('\\s+', ' ') %>%
  str_replace_all('\\s*([^,\\()]+ =) (c\\()', '\n  \\1\n    \\2')  %>%
  str_replace_all('(,) (class =)', '\\1\n  \\2') %>%
  write_clip(allow_non_interactive = TRUE)
  1. If the data is just too long or wide, subset the columns, easily with
my_data %>% select(var1, var2 ...) -> for_example # or
my_data[1:4] -> for_example
  1. For two many rows, either upload a csv to S3 or a github gist and provide a link or (preferably) a readr::read_csv([URL])
head(my_data,16) -> for_example # whatever number is needed to illustrate the issue
  1. For private my_data, either anonymize, or adapt a standard data set, such as mtcars to mimic the my_data structure

Hi Richard
Thank you for the info to create reprex

I have the following reprex

read_file(sales1)
library(tidyverse)
library(psy)

#Number of rows before to take into account
rolling = 2

sales1 <- sales::sales(
~date, ~sales,)
#Lag
sales1 = sales1 %>% mutate(lagsales = lag(sales))

#Get the rolling alpha
sales1$alpha = c(
rep(NA, rolling),
map_dbl((rolling + 1):nrow(sales1), function(x){
cronbach(sales1 %>% select(sales, lagsales) %>% slice((x-rolling):x))$alpha
})
)
sales1

output:

A tibble: 341 x 4

Date sales lagsales alpha

1 03-01-2017 40 NA NA
2 04-01-2017 2 40 NA
3 05-01-2017 2 2 0
4 06-01-2017 2 2 0
5 07-01-2017 30 2 0
6 08-01-2017 2 30 -2
7 01-02-2017 9 2 -4.44
8 02-02-2017 5 9 -1.48
9 03-02-2017 65 5 -0.0604
10 04-02-2017 3 65 -2.69

I have used the incorrect alpha (chronbach) instead of the Holtwinters Alpha.
Not sure if you know what Triple Multiplicative Holtwinters Alpha, beta and Gamma analyses means. :slight_smile: But those are the ones i need in my table.

I thought the following code would attribute to the code.But i dont know how to fit it in.

HoltWinters(sales1, alpha = null, beta = null, gamma = null,
seasonal = c("additive", "multiplicative"),
start.periods = 2, l.start = NULL, b.start = NULL,
s.start = NULL,
optim.start = c(alpha = 0.3, beta = 0.1, gamma = 0.1),
optim.control = list(k))

cheers

This is what a the data part of a reprex data looks like

sales <- structure(
  list(
    confirmed =
      c(
        2,
        5,
        18,
        28,
        43,
        61,
        95,
        139,
        245,
        388,
        593,
        978,
        1501,
        2336,
        2922,
        3513,
        4747,
        5823,
        6566,
        7161,
        8042,
        9000,
        10075,
        11364,
        12729,
        13938,
        14991,
        16169,
        17361,
        18407,
        19644,
        20610,
        21638,
        23049,
        24811,
        27017,
        29406,
        32332,
        35408,
        38309
      ),
    deaths =
      c(
        2,
        2,
        4,
        5,
        8,
        12,
        16,
        19,
        26,
        34,
        43,
        54,
        66,
        77,
        92,
        107,
        124,
        145,
        194,
        237,
        291,
        354,
        429,
        514,
        611,
        724,
        853,
        988,
        1135,
        1284,
        1433,
        1556,
        1685,
        1812,
        1934,
        2077,
        2234,
        2378,
        2517,
        2640
      ),
    recovered =
      c(
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        49,
        49,
        73,
        123,
        175,
        291,
        291,
        552,
        739,
        913,
        1669,
        2134,
        2394,
        2731,
        2959,
        2959,
        2959,
        2959,
        4590,
        4590,
        5389,
        5389,
        5710,
        6745,
        7635,
        7931,
        7931,
        8913,
        9625,
        10457,
        11133,
        11679,
        12391
      )
  ),
  class =
    c("spec_tbl_df", "tbl_df", "tbl", "data.frame"),
  row.names =
    c(NA,-40L),
  spec = structure(list(
    cols = list(
      confirmed = structure(list(),
                            class =
                              c("collector_double", "collector")),
      deaths = structure(list(),
                         class =
                           c("collector_double", "collector")),
      recovered = structure(list(),
                            class =
                              c("collector_double", "collector"))
    ),
    default = structure(list(),
                        class =
                          c("collector_guess", "collector")),
    skip = 1
  ),
  class = "col_spec")
)

sales
#>    confirmed deaths recovered
#> 1          2      2         0
#> 2          5      2         0
#> 3         18      4         0
#> 4         28      5         0
#> 5         43      8         0
#> 6         61     12         0
#> 7         95     16         0
#> 8        139     19        49
#> 9        245     26        49
#> 10       388     34        73
#> 11       593     43       123
#> 12       978     54       175
#> 13      1501     66       291
#> 14      2336     77       291
#> 15      2922     92       552
#> 16      3513    107       739
#> 17      4747    124       913
#> 18      5823    145      1669
#> 19      6566    194      2134
#> 20      7161    237      2394
#> 21      8042    291      2731
#> 22      9000    354      2959
#> 23     10075    429      2959
#> 24     11364    514      2959
#> 25     12729    611      2959
#> 26     13938    724      4590
#> 27     14991    853      4590
#> 28     16169    988      5389
#> 29     17361   1135      5389
#> 30     18407   1284      5710
#> 31     19644   1433      6745
#> 32     20610   1556      7635
#> 33     21638   1685      7931
#> 34     23049   1812      7931
#> 35     24811   1934      8913
#> 36     27017   2077      9625
#> 37     29406   2234     10457
#> 38     32332   2378     11133
#> 39     35408   2517     11679
#> 40     38309   2640     12391

Created on 2020-04-05 by the reprex package (v0.3.0)

To create it, you can use this function

require(clipr)
#> Loading required package: clipr
#> Welcome to clipr. See ?write_clip for advisories on writing to the clipboard in R.
require(magrittr)
#> Loading required package: magrittr
require(stringr)
#> Loading required package: stringr

specimen <- function(x)
  deparse(x) %>%
  str_c(collapse = '') %>%
  str_replace_all('\\s+', ' ') %>%
  str_replace_all('\\s*([^,\\()]+ =) (c\\()', '\n  \\1\n    \\2')  %>%
  str_replace_all('(,) (class =)', '\\1\n  \\2') %>%
  write_clip(allow_non_interactive = TRUE)

by

specimen(sales)

and just cutting and pasting into the post.

It would be nice to have the rest of the code, too, but that is a bare minimum

Hi Richard,

I have been busy for a whole day to get a reprex.
I loaded several packages from shiny to reprex.
When i try to run the rendering, it get execution errors in version3.5

My sample data (taken from my file )looks like

ate sales
03-01-2017 40
04-01-2017 2
05-01-2017 2
06-01-2017 2
07-01-2017 30
08-01-2017 2
01-02-2017 9
02-02-2017 5
03-02-2017 65
04-02-2017 3
05-02-2017 65
06-02-2017 1
07-02-2017 11
08-02-2017 9
01-03-2017 21
02-03-2017 65
03-03-2017 5
04-03-2017 10
05-03-2017 40
06-03-2017 2
07-03-2017 2
08-03-2017 2
09-03-2017 30
01-04-2017 2
02-04-2017 9
03-04-2017 5
04-04-2017 65
05-04-2017 3
06-04-2017 65
07-04-2017 1
08-04-2017 33
09-04-2017 33
01-05-2017 21
02-05-2017 65
03-05-2017 587

Referring to my earlier code i am trying to get the Alpha, Beta and gamma (holtwinters)

read_file(sales1)
library(tidyverse)
library(psy)

#Number of rows before to take into account
rolling = 2

sales1 <- sales::sales(
~date, ~sales,)
#Lag
sales1 = sales1 %>% mutate(lagsales = lag(sales))

#Get the rolling alpha
sales1$alpha = c(
rep(NA, rolling),
map_dbl((rolling + 1):nrow(sales1), function(x){
cronbach(sales1 %>% select(sales, lagsales) %>% slice((x-rolling):x))$alpha
})
)
sales1

I tried to find it by looking at the following example:

HoltWinters(x, alpha = NULL, beta = NULL, gamma = NULL,

seasonal = c("additive", "multiplicative"),

start.periods = 2, l.start = NULL, b.start = NULL,

s.start = NULL,

optim.start = c(alpha = 0.3, beta = 0.1, gamma = 0.1),

optim.control = list())

Arguments

x An object of class ts
alpha alpha parameter of Holt-Winters Filter.
beta beta parameter of Holt-Winters Filter. If set to FALSE , the function will do exponential smoothing.
gamma gamma parameter used for the seasonal component. If set to FALSE , an non-seasonal model is fitted.
seasonal Character string to select an "additive" (the default) or "multiplicative" seasonal model. The first few characters are sufficient. (Only takes effect if gamma is non-zero).
start.periods Start periods used in the autodetection of start values. Must be at least 2.
l.start Start value for level (a[0]).
b.start Start value for trend (b[0]).
s.start Vector of start values for the seasonal component ( s_1[0] … s_p[0] )
optim.start Vector with named components alpha , beta , and gamma containing the starting values for the optimizer. Only the values needed must be specified. Ignored in the one-parameter case.
optim.control Optional list with additional control parameters passed to optim if this is used. Ignored in the one-parameter case.

Hi Richard

Please find below the reprex.
I tried to follow your example. The data is a sample of my xl sheet. I have no formula for the Holtwinters Alpha.(AlphaHW) This is where I am looking for help for.

sales <- structure(
list(
sales=
c(
6,
5,
18,
8,
43,
61,
95,
139,
45,
88,
93,
98,
11,
336,
9,
313,
47,
583,
66,
61,
4,
90,
15,
13,
19,
18,
11,
19,
61,
17,
144,
40,
38,
309,
41,
77,
96,
33,
8,
39
),
return =
c(
2,
3,
4,
5,
8,
1,
16,
19,
6,
34,
43,
54,
66,
77,
9,
107,
14,
145,
194,
37,
91,
354,
49,
514,
611,
74,
83,
98,
35,
18,
133,
56,
15,
181,
34,
77,
34,
38,
57,
60
),
AlphaHW =
c(
1,
2,
6,
3,
3,
7,
2,
49,
49,
73,
13,
15,
91,
91,
5,
79,
93,
69,
34,
94,
31,
59,
59,
9,
9,
40,
90,
59,
59,
50,
65,
35,
31,
79,
3,
95,
17,
33,
79,
91
)
),
class =
c("spec_tbl_df", "tbl_df", "tbl", "data.frame"),
row.names =
c(NA,-40L),
spec = structure(list(
cols = list(
sales = structure(list(),
class =
c("collector_double", "collector")),
sales = structure(list(),
class =
c("collector_double", "collector")),
return = structure(list(),
class =
c("collector_double", "collector"))
),
default = structure(list(),
class =
c("collector_guess", "collector")),
skip = 1
),
class = "col_spec")
)

sales

#output:

sales return AlphaHW
1 6 2 1
2 5 3 2
3 18 4 6
4 8 5 3
5 43 8 3
6 61 1 7
7 95 16 2
8 139 19 49
9 45 6 49
10 88 34 73
11 93 43 13
12 98 54 15
13 11 66 91
14 336 77 91
15 9 9 5
16 313 107 79
17 47 14 93
18 583 145 69
19 66 194 34
20 61 37 94
21 4 91 31
22 90 354 59
23 15 49 59
24 13 514 9
25 19 611 9
26 18 74 40
27 11 83 90
28 19 98 59
29 61 35 59
30 17 18 50
31 144 133 65
32 40 56 35
33 38 15 31
34 309 181 79
35 41 34 3
36 77 77 95
37 96 34 17
38 33 38 33
39 8 57 79
40 39 60 91

suppressPackageStartupMessages(library(dplyr)) 
suppressPackageStartupMessages(library(lubridate)) 
suppressPackageStartupMessages(library(tibble)) 

sales <-  c(6, 5, 18, 8, 43, 61, 95, 139, 45, 88, 93, 98, 11, 336, 9, 313, 47, 583, 66, 61, 4, 90, 15, 13, 19, 18, 11, 19, 61, 17, 144, 40, 38, 309, 41, 77, 96, 33, 8, 39)


ts(sales, start = ymd("2017-03-01"), frequency = 12) -> sales_alpha

HoltWinters(sales_alpha) -> sales_hw

plot(sales_hw)

plot(fitted(sales_hw))

Created on 2020-04-12 by the reprex package (v0.3.0)

1 Like

Hi ,
Thank you so much. I will test the script and let you know .
Cheers

1 Like