Introduction
expss
computes and displays tables with support for
‘SPSS’-style labels, multiple / nested banners, weights,
multiple-response variables and significance testing. There are
facilities for nice output of tables in ‘knitr’, R notebooks, ‘Shiny’
and ‘Jupyter’ notebooks. Proper methods for labelled variables add value
labels support to base R functions and to some functions from other
packages. Additionally, the package offers useful functions for data
processing in marketing research / social surveys - popular data
transformation functions from ‘SPSS’ Statistics and ‘Excel’ (‘RECODE’,
‘COUNT’, ‘COUNTIF’, ‘VLOOKUP’, etc.). Package is intended to help people
to move data processing from ‘Excel’/‘SPSS’ to R. See examples below.
You can get help about any function by typing
?function_name
in the R console.
Installation
expss
is on CRAN, so for installation you can print in
the console install.packages("expss")
.
Cross-tablulation examples
We will use for demonstartion well-known mtcars
dataset.
Let’s start with adding labels to the dataset. Then we can continue with
tables creation.
library(expss)
data(mtcars)
mtcars = apply_labels(mtcars,
mpg = "Miles/(US) gallon",
cyl = "Number of cylinders",
disp = "Displacement (cu.in.)",
hp = "Gross horsepower",
drat = "Rear axle ratio",
wt = "Weight (1000 lbs)",
qsec = "1/4 mile time",
vs = "Engine",
vs = c("V-engine" = 0,
"Straight engine" = 1),
am = "Transmission",
am = c("Automatic" = 0,
"Manual"=1),
gear = "Number of forward gears",
carb = "Number of carburetors"
)
For quick cross-tabulation there are fre
and
cross
family of function. For simplicity we demonstrate
here only cross_cpct
which calculates column percent.
Documentation for other functions, such as cross_cases
for
counts, cross_rpct
for row percent, cross_tpct
for table percent and cross_fun
for custom summary
functions can be seen by typing ?cross_cpct
and
?cross_fun
in the console.
# 'cross_*' examples
# just simple crosstabulation, similar to base R 'table' function
cross_cases(mtcars, am, vs)
|
Engine
|
|
V-engine
|
Straight engine
|
Transmission
|
Automatic
|
12
|
7
|
Manual
|
6
|
7
|
#Total cases
|
18
|
14
|
# Table column % with multiple banners
cross_cpct(mtcars, cyl, list(total(), am, vs))
|
#Total
|
|
Transmission
|
|
Engine
|
|
|
|
Automatic
|
Manual
|
|
V-engine
|
Straight engine
|
Number of cylinders
|
4
|
34.4
|
|
15.8
|
61.5
|
|
5.6
|
71.4
|
6
|
21.9
|
|
21.1
|
23.1
|
|
16.7
|
28.6
|
8
|
43.8
|
|
63.2
|
15.4
|
|
77.8
|
|
#Total cases
|
32
|
|
19
|
13
|
|
18
|
14
|
# magrittr pipe usage and nested banners
mtcars %>%
cross_cpct(cyl, list(total(), am %nest% vs))
|
#Total
|
|
Transmission
|
|
|
|
Automatic
|
|
Manual
|
|
|
|
Engine
|
|
Engine
|
|
|
|
V-engine
|
Straight engine
|
|
V-engine
|
Straight engine
|
Number of cylinders
|
4
|
34.4
|
|
|
42.9
|
|
16.7
|
100
|
6
|
21.9
|
|
|
57.1
|
|
50.0
|
|
8
|
43.8
|
|
100
|
|
|
33.3
|
|
#Total cases
|
32
|
|
12
|
7
|
|
6
|
7
|
We have more sophisticated interface for table construction with
magrittr
piping. Table construction consists of at least of
three functions chained with pipe operator: %>%
. At
first we need to specify variables for which statistics will be computed
with tab_cells
. Secondary, we calculate statistics with one
of the tab_stat_*
functions. And last, we finalize table
creation with tab_pivot
, e. g.:
dataset %>% tab_cells(variable) %>% tab_stat_cases() %>% tab_pivot()
.
After that we can optionally sort table with tab_sort_asc
,
drop empty rows/columns with drop_rc
and transpose with
tab_transpose
. Resulting table is just a
data.frame
so we can use usual R operations on it. Detailed
documentation for table creation can be seen via ?tables
.
For significance testing see ?significance
. Generally,
tables automatically translated to HTML for output in knitr or Jupyter
notebooks. However, if we want HTML output in the R notebooks or in the
RStudio viewer we need to set options for that:
expss_output_rnotebook()
or
expss_output_viewer()
.
# simple example
mtcars %>%
tab_cells(cyl) %>%
tab_cols(total(), am) %>%
tab_stat_cpct() %>%
tab_pivot()
|
#Total
|
|
Transmission
|
|
|
|
Automatic
|
Manual
|
Number of cylinders
|
4
|
34.4
|
|
15.8
|
61.5
|
6
|
21.9
|
|
21.1
|
23.1
|
8
|
43.8
|
|
63.2
|
15.4
|
#Total cases
|
32
|
|
19
|
13
|
# table with caption
mtcars %>%
tab_cells(mpg, disp, hp, wt, qsec) %>%
tab_cols(total(), am) %>%
tab_stat_mean_sd_n() %>%
tab_last_sig_means(subtable_marks = "both") %>%
tab_pivot() %>%
set_caption("Table with summary statistics and significance marks.")
Table with summary statistics and significance marks.
|
|
#Total
|
|
Transmission
|
|
|
|
Automatic
|
|
Manual
|
|
|
|
A
|
|
B
|
Miles/(US) gallon
|
Mean
|
20.1
|
|
17.1 < B
|
|
24.4 > A
|
Std. dev.
|
6.0
|
|
3.8
|
|
6.2
|
Unw. valid N
|
32.0
|
|
19.0
|
|
13.0
|
Displacement (cu.in.)
|
Mean
|
230.7
|
|
290.4 > B
|
|
143.5 < A
|
Std. dev.
|
123.9
|
|
110.2
|
|
87.2
|
Unw. valid N
|
32.0
|
|
19.0
|
|
13.0
|
Gross horsepower
|
Mean
|
146.7
|
|
160.3
|
|
126.8
|
Std. dev.
|
68.6
|
|
53.9
|
|
84.1
|
Unw. valid N
|
32.0
|
|
19.0
|
|
13.0
|
Weight (1000 lbs)
|
Mean
|
3.2
|
|
3.8 > B
|
|
2.4 < A
|
Std. dev.
|
1.0
|
|
0.8
|
|
0.6
|
Unw. valid N
|
32.0
|
|
19.0
|
|
13.0
|
1/4 mile time
|
Mean
|
17.8
|
|
18.2
|
|
17.4
|
Std. dev.
|
1.8
|
|
1.8
|
|
1.8
|
Unw. valid N
|
32.0
|
|
19.0
|
|
13.0
|
# Table with the same summary statistics. Statistics labels in columns.
mtcars %>%
tab_cells(mpg, disp, hp, wt, qsec) %>%
tab_cols(total(label = "#Total| |"), am) %>%
tab_stat_fun(Mean = w_mean, "Std. dev." = w_sd, "Valid N" = w_n, method = list) %>%
tab_pivot()
|
#Total
|
|
Transmission
|
|
|
|
Automatic
|
|
Manual
|
|
Mean
|
Std. dev.
|
Valid N
|
|
Mean
|
Std. dev.
|
Valid N
|
|
Mean
|
Std. dev.
|
Valid N
|
Miles/(US) gallon
|
20.1
|
6.0
|
32
|
|
17.1
|
3.8
|
19
|
|
24.4
|
6.2
|
13
|
Displacement (cu.in.)
|
230.7
|
123.9
|
32
|
|
290.4
|
110.2
|
19
|
|
143.5
|
87.2
|
13
|
Gross horsepower
|
146.7
|
68.6
|
32
|
|
160.3
|
53.9
|
19
|
|
126.8
|
84.1
|
13
|
Weight (1000 lbs)
|
3.2
|
1.0
|
32
|
|
3.8
|
0.8
|
19
|
|
2.4
|
0.6
|
13
|
1/4 mile time
|
17.8
|
1.8
|
32
|
|
18.2
|
1.8
|
19
|
|
17.4
|
1.8
|
13
|
# Different statistics for different variables.
mtcars %>%
tab_cols(total(), vs) %>%
tab_cells(mpg) %>%
tab_stat_mean() %>%
tab_stat_valid_n() %>%
tab_cells(am) %>%
tab_stat_cpct(total_row_position = "none", label = "col %") %>%
tab_stat_rpct(total_row_position = "none", label = "row %") %>%
tab_stat_tpct(total_row_position = "none", label = "table %") %>%
tab_pivot(stat_position = "inside_rows")
|
|
|
#Total
|
|
Engine
|
|
|
|
|
|
V-engine
|
Straight engine
|
Miles/(US) gallon
|
Mean
|
|
|
20.1
|
|
16.6
|
24.6
|
Valid N
|
|
|
32.0
|
|
18.0
|
14.0
|
Transmission
|
Automatic
|
col %
|
|
59.4
|
|
66.7
|
50.0
|
|
row %
|
|
100.0
|
|
63.2
|
36.8
|
|
table %
|
|
59.4
|
|
37.5
|
21.9
|
Manual
|
col %
|
|
40.6
|
|
33.3
|
50.0
|
|
row %
|
|
100.0
|
|
46.2
|
53.8
|
|
table %
|
|
40.6
|
|
18.8
|
21.9
|
# Table with split by rows and with custom totals.
mtcars %>%
tab_cells(cyl) %>%
tab_cols(total(), vs) %>%
tab_rows(am) %>%
tab_stat_cpct(total_row_position = "above",
total_label = c("number of cases", "row %"),
total_statistic = c("u_cases", "u_rpct")) %>%
tab_pivot()
|
|
|
#Total
|
|
Engine
|
|
|
|
|
|
|
V-engine
|
Straight engine
|
Transmission
|
Automatic
|
Number of cylinders
|
#number of cases
|
|
19
|
|
12
|
7
|
|
|
#row %
|
|
100
|
|
63.2
|
36.8
|
|
|
4
|
|
15.8
|
|
|
42.9
|
|
|
6
|
|
21.1
|
|
|
57.1
|
|
|
8
|
|
63.2
|
|
100.0
|
|
Manual
|
Number of cylinders
|
#number of cases
|
|
13
|
|
6
|
7
|
|
|
#row %
|
|
100
|
|
46.2
|
53.8
|
|
|
4
|
|
61.5
|
|
16.7
|
100.0
|
|
|
6
|
|
23.1
|
|
50.0
|
|
|
|
8
|
|
15.4
|
|
33.3
|
|
# Linear regression by groups.
mtcars %>%
tab_cells(sheet(mpg, disp, hp, wt, qsec)) %>%
tab_cols(total(label = "#Total| |"), am) %>%
tab_stat_fun_df(
function(x){
frm = reformulate(".", response = as.name(names(x)[1]))
model = lm(frm, data = x)
sheet('Coef.' = coef(model),
confint(model)
)
}
) %>%
tab_pivot()
|
#Total
|
|
Transmission
|
|
|
|
Automatic
|
|
Manual
|
|
Coef.
|
2.5 %
|
97.5 %
|
|
Coef.
|
2.5 %
|
97.5 %
|
|
Coef.
|
2.5 %
|
97.5 %
|
(Intercept)
|
27.3
|
9.6
|
45.1
|
|
21.8
|
-1.9
|
45.5
|
|
13.3
|
-21.9
|
48.4
|
Displacement (cu.in.)
|
0.0
|
0.0
|
0.0
|
|
0.0
|
0.0
|
0.0
|
|
0.0
|
-0.1
|
0.1
|
Gross horsepower
|
0.0
|
-0.1
|
0.0
|
|
0.0
|
-0.1
|
0.0
|
|
0.0
|
0.0
|
0.1
|
Weight (1000 lbs)
|
-4.6
|
-7.2
|
-2.0
|
|
-2.3
|
-5.0
|
0.4
|
|
-7.7
|
-12.5
|
-2.9
|
1/4 mile time
|
0.5
|
-0.4
|
1.5
|
|
0.4
|
-0.7
|
1.6
|
|
1.6
|
-0.2
|
3.4
|
Example of data processing with multiple-response variables
Here we use truncated dataset with data from product test of two
samples of chocolate sweets. 150 respondents tested two kinds of sweets
(codenames: VSX123 and SDF546). Sample was divided into two groups
(cells) of 75 respondents in each group. In cell 1 product VSX123 was
presented first and then SDF546. In cell 2 sweets were presented in
reversed order. Questions about respondent impressions about first
product are in the block A (and about second tested product in the block
B). At the end of the questionnaire there was a question about the
preferences between sweets.
List of variables:
id
Respondent Id
cell
First tested product (cell number)
s2a
Age
a1_1-a1_6
What did you like in these sweets? Multiple
response. First tested product
a22
Overall quality. First tested product
b1_1-b1_6
What did you like in these sweets? Multiple
response. Second tested product
b22
Overall quality. Second tested product
c1
Preferences
data(product_test)
w = product_test # shorter name to save some keystrokes
# here we recode variables from first/second tested product to separate variables for each product according to their cells
# 'h' variables - VSX123 sample, 'p' variables - 'SDF456' sample
# also we recode preferences from first/second product to true names
# for first cell there are no changes, for second cell we should exchange 1 and 2.
w = w %>%
let_if(cell == 1,
h1_1 %to% h1_6 := recode(a1_1 %to% a1_6, other ~ copy),
p1_1 %to% p1_6 := recode(b1_1 %to% b1_6, other ~ copy),
h22 := recode(a22, other ~ copy),
p22 := recode(b22, other ~ copy),
c1r = c1
) %>%
let_if(cell == 2,
p1_1 %to% p1_6 := recode(a1_1 %to% a1_6, other ~ copy),
h1_1 %to% h1_6 := recode(b1_1 %to% b1_6, other ~ copy),
p22 := recode(a22, other ~ copy),
h22 := recode(b22, other ~ copy),
c1r := recode(c1, 1 ~ 2, 2 ~ 1, other ~ copy)
) %>%
let(
# recode age by groups
age_cat = recode(s2a, lo %thru% 25 ~ 1, lo %thru% hi ~ 2),
# count number of likes
# codes 2 and 99 are ignored.
h_likes = count_row_if(1 | 3 %thru% 98, h1_1 %to% h1_6),
p_likes = count_row_if(1 | 3 %thru% 98, p1_1 %to% p1_6)
)
# here we prepare labels for future usage
codeframe_likes = num_lab("
1 Liked everything
2 Disliked everything
3 Chocolate
4 Appearance
5 Taste
6 Stuffing
7 Nuts
8 Consistency
98 Other
99 Hard to answer
")
overall_liking_scale = num_lab("
1 Extremely poor
2 Very poor
3 Quite poor
4 Neither good, nor poor
5 Quite good
6 Very good
7 Excellent
")
w = apply_labels(w,
c1r = "Preferences",
c1r = num_lab("
1 VSX123
2 SDF456
3 Hard to say
"),
age_cat = "Age",
age_cat = c("18 - 25" = 1, "26 - 35" = 2),
h1_1 = "Likes. VSX123",
p1_1 = "Likes. SDF456",
h1_1 = codeframe_likes,
p1_1 = codeframe_likes,
h_likes = "Number of likes. VSX123",
p_likes = "Number of likes. SDF456",
h22 = "Overall quality. VSX123",
p22 = "Overall quality. SDF456",
h22 = overall_liking_scale,
p22 = overall_liking_scale
)
Are there any significant differences between preferences? Yes,
difference is significant.
# 'tab_mis_val(3)' remove 'hard to say' from vector
w %>% tab_cols(total(), age_cat) %>%
tab_cells(c1r) %>%
tab_mis_val(3) %>%
tab_stat_cases() %>%
tab_last_sig_cases() %>%
tab_pivot()
|
#Total
|
|
Age
|
|
|
|
18 - 25
|
26 - 35
|
Preferences
|
VSX123
|
94.0
|
|
46.0
|
48.0
|
SDF456
|
50.0
|
|
22.0
|
28.0
|
Hard to say
|
|
|
|
|
#Chi-squared p-value
|
<0.05
|
|
(warn.)
|
|
#Total cases
|
144.0
|
|
68.0
|
76.0
|
Further we calculate distribution of answers in the survey
questions.
# lets specify repeated parts of table creation chains
banner = w %>% tab_cols(total(), age_cat, c1r)
# column percent with significance
tab_cpct_sig = . %>% tab_stat_cpct() %>%
tab_last_sig_cpct(sig_labels = paste0("<b>",LETTERS, "</b>"))
# means with siginifcance
tab_means_sig = . %>% tab_stat_mean_sd_n(labels = c("<b><u>Mean</u></b>", "sd", "N")) %>%
tab_last_sig_means(
sig_labels = paste0("<b>",LETTERS, "</b>"),
keep = "means")
# Preferences
banner %>%
tab_cells(c1r) %>%
tab_cpct_sig() %>%
tab_pivot()
|
#Total
|
|
Age
|
|
Preferences
|
|
|
|
18 - 25
|
|
26 - 35
|
|
VSX123
|
|
SDF456
|
|
Hard to say
|
|
|
|
A
|
|
B
|
|
A
|
|
B
|
|
C
|
Preferences
|
VSX123
|
62.7
|
|
65.7
|
|
60.0
|
|
100.0
|
|
|
|
|
SDF456
|
33.3
|
|
31.4
|
|
35.0
|
|
|
|
100.0
|
|
|
Hard to say
|
4.0
|
|
2.9
|
|
5.0
|
|
|
|
|
|
100.0
|
#Total cases
|
150
|
|
70
|
|
80
|
|
94
|
|
50
|
|
6
|
# Overall liking
banner %>%
tab_cells(h22) %>%
tab_means_sig() %>%
tab_cpct_sig() %>%
tab_cells(p22) %>%
tab_means_sig() %>%
tab_cpct_sig() %>%
tab_pivot()
|
#Total
|
|
Age
|
|
Preferences
|
|
|
|
18 - 25
|
|
26 - 35
|
|
VSX123
|
|
SDF456
|
|
Hard to say
|
|
|
|
A
|
|
B
|
|
A
|
|
B
|
|
C
|
Overall quality. VSX123
|
Mean
|
5.5
|
|
5.4
|
|
5.6
|
|
5.3
|
|
5.8 A
|
|
5.5
|
Extremely poor
|
|
|
|
|
|
|
|
|
|
|
|
Very poor
|
|
|
|
|
|
|
|
|
|
|
|
Quite poor
|
2.0
|
|
2.9
|
|
1.2
|
|
3.2
|
|
|
|
|
Neither good, nor poor
|
10.7
|
|
11.4
|
|
10.0
|
|
14.9 B
|
|
2.0
|
|
16.7
|
Quite good
|
39.3
|
|
45.7
|
|
33.8
|
|
40.4
|
|
38.0
|
|
33.3
|
Very good
|
33.3
|
|
24.3
|
|
41.2 A
|
|
30.9
|
|
38.0
|
|
33.3
|
Excellent
|
14.7
|
|
15.7
|
|
13.8
|
|
10.6
|
|
22.0
|
|
16.7
|
#Total cases
|
150
|
|
70
|
|
80
|
|
94
|
|
50
|
|
6
|
Overall quality. SDF456
|
Mean
|
5.4
|
|
5.3
|
|
5.4
|
|
5.4
|
|
5.3
|
|
5.7
|
Extremely poor
|
|
|
|
|
|
|
|
|
|
|
|
Very poor
|
0.7
|
|
|
|
1.2
|
|
1.1
|
|
|
|
|
Quite poor
|
2.7
|
|
4.3
|
|
1.2
|
|
2.1
|
|
4.0
|
|
|
Neither good, nor poor
|
16.7
|
|
20.0
|
|
13.8
|
|
18.1
|
|
14.0
|
|
16.7
|
Quite good
|
31.3
|
|
27.1
|
|
35.0
|
|
28.7
|
|
38.0
|
|
16.7
|
Very good
|
35.3
|
|
35.7
|
|
35.0
|
|
35.1
|
|
34.0
|
|
50.0
|
Excellent
|
13.3
|
|
12.9
|
|
13.8
|
|
14.9
|
|
10.0
|
|
16.7
|
#Total cases
|
150
|
|
70
|
|
80
|
|
94
|
|
50
|
|
6
|
# Likes
banner %>%
tab_cells(h_likes) %>%
tab_means_sig() %>%
tab_cells(mrset(h1_1 %to% h1_6)) %>%
tab_cpct_sig() %>%
tab_cells(p_likes) %>%
tab_means_sig() %>%
tab_cells(mrset(p1_1 %to% p1_6)) %>%
tab_cpct_sig() %>%
tab_pivot()
|
#Total
|
|
Age
|
|
Preferences
|
|
|
|
18 - 25
|
|
26 - 35
|
|
VSX123
|
|
SDF456
|
|
Hard to say
|
|
|
|
A
|
|
B
|
|
A
|
|
B
|
|
C
|
Number of likes. VSX123
|
Mean
|
2.0
|
|
2.0
|
|
2.1
|
|
1.9
|
|
2.2
|
|
2.3
|
Likes. VSX123
|
Liked everything
|
|
|
|
|
|
|
|
|
|
|
|
Disliked everything
|
3.3
|
|
1.4
|
|
5.0
|
|
4.3
|
|
2.0
|
|
|
Chocolate
|
34.0
|
|
38.6
|
|
30.0
|
|
35.1
|
|
32.0
|
|
33.3
|
Appearance
|
29.3
|
|
21.4
|
|
36.2 A
|
|
25.5
|
|
38.0
|
|
16.7
|
Taste
|
32.0
|
|
38.6
|
|
26.2
|
|
23.4
|
|
48.0 A
|
|
33.3
|
Stuffing
|
27.3
|
|
20.0
|
|
33.8
|
|
28.7
|
|
26.0
|
|
16.7
|
Nuts
|
66.7
|
|
72.9
|
|
61.3
|
|
69.1
|
|
60.0
|
|
83.3
|
Consistency
|
12.0
|
|
4.3
|
|
18.8 A
|
|
8.5
|
|
14.0
|
|
50.0 A B
|
Other
|
|
|
|
|
|
|
|
|
|
|
|
Hard to answer
|
|
|
|
|
|
|
|
|
|
|
|
#Total cases
|
150
|
|
70
|
|
80
|
|
94
|
|
50
|
|
6
|
Number of likes. SDF456
|
Mean
|
2.0
|
|
2.0
|
|
2.1
|
|
2.0
|
|
2.0
|
|
2.0
|
Likes. SDF456
|
Liked everything
|
|
|
|
|
|
|
|
|
|
|
|
Disliked everything
|
1.3
|
|
1.4
|
|
1.2
|
|
2.1
|
|
|
|
|
Chocolate
|
32.0
|
|
27.1
|
|
36.2
|
|
29.8
|
|
34.0
|
|
50.0
|
Appearance
|
32.0
|
|
35.7
|
|
28.7
|
|
34.0
|
|
30.0
|
|
16.7
|
Taste
|
39.3
|
|
42.9
|
|
36.2
|
|
36.2
|
|
44.0
|
|
50.0
|
Stuffing
|
27.3
|
|
24.3
|
|
30.0
|
|
31.9
|
|
20.0
|
|
16.7
|
Nuts
|
61.3
|
|
60.0
|
|
62.5
|
|
58.5
|
|
68.0
|
|
50.0
|
Consistency
|
10.0
|
|
5.7
|
|
13.8
|
|
11.7
|
|
6.0
|
|
16.7
|
Other
|
0.7
|
|
|
|
1.2
|
|
1.1
|
|
|
|
|
Hard to answer
|
|
|
|
|
|
|
|
|
|
|
|
#Total cases
|
150
|
|
70
|
|
80
|
|
94
|
|
50
|
|
6
|
# below more complicated table where we compare likes side by side
# Likes - side by side comparison
w %>%
tab_cols(total(label = "#Total| |"), c1r) %>%
tab_cells(list(unvr(mrset(h1_1 %to% h1_6)))) %>%
tab_stat_cpct(label = var_lab(h1_1)) %>%
tab_cells(list(unvr(mrset(p1_1 %to% p1_6)))) %>%
tab_stat_cpct(label = var_lab(p1_1)) %>%
tab_pivot(stat_position = "inside_columns")
|
#Total
|
|
Preferences
|
|
|
|
VSX123
|
|
SDF456
|
|
Hard to say
|
|
Likes. VSX123
|
Likes. SDF456
|
|
Likes. VSX123
|
Likes. SDF456
|
|
Likes. VSX123
|
Likes. SDF456
|
|
Likes. VSX123
|
Likes. SDF456
|
Liked everything
|
|
|
|
|
|
|
|
|
|
|
|
Disliked everything
|
3.3
|
1.3
|
|
4.3
|
2.1
|
|
2
|
|
|
|
|
Chocolate
|
34.0
|
32.0
|
|
35.1
|
29.8
|
|
32
|
34
|
|
33.3
|
50.0
|
Appearance
|
29.3
|
32.0
|
|
25.5
|
34.0
|
|
38
|
30
|
|
16.7
|
16.7
|
Taste
|
32.0
|
39.3
|
|
23.4
|
36.2
|
|
48
|
44
|
|
33.3
|
50.0
|
Stuffing
|
27.3
|
27.3
|
|
28.7
|
31.9
|
|
26
|
20
|
|
16.7
|
16.7
|
Nuts
|
66.7
|
61.3
|
|
69.1
|
58.5
|
|
60
|
68
|
|
83.3
|
50.0
|
Consistency
|
12.0
|
10.0
|
|
8.5
|
11.7
|
|
14
|
6
|
|
50.0
|
16.7
|
Other
|
|
0.7
|
|
|
1.1
|
|
|
|
|
|
|
Hard to answer
|
|
|
|
|
|
|
|
|
|
|
|
#Total cases
|
150
|
150
|
|
94
|
94
|
|
50
|
50
|
|
6
|
6
|
We can save labelled dataset as *.csv file with accompanying R code
for labelling.
write_labelled_csv(w, file filename = "product_test.csv")
Or, we can save dataset as *.csv file with SPSS syntax to read data
and apply labels.
write_labelled_spss(w, file filename = "product_test.csv")