Вот один способ с table
и addmargins
out <- addmargins(table(unlist(df1), c(col(df1))), 2)
cbind(out, Percentage = 100 *out[,4]/sum(out[, 4]))
# 1 2 3 Sum Percentage
#M 1 0 1 2 16.66667
#P 1 1 2 4 33.33333
#Z 2 3 1 6 50.00000
Или более компактно
library(qdapTools)
transform(as.data.frame(addmargins(t(mtabulate(df1)), 2)),
Percentage = 100 * Sum/sum(Sum))
Или используя tidyverse
library(tidyverse)
gather(df1, key, Factor) %>%
dplyr::count(key, Factor) %>%
spread(key, n, fill = 0) %>%
mutate(Freq = rowSums(.[-1]),
Percentage = 100 * Freq/sum(Freq))
# A tibble: 3 x 6
# Factor v1 v2 v3 Freq Percentage
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 M 1 0 1 2 16.7
#2 P 1 1 2 4 33.3
#3 Z 2 3 1 6 50
данные
df1 <- structure(list(v1 = c("M", "Z", "P", "Z"), v2 = c("Z", "Z", "Z",
"P"), v3 = c("P", "P", "M", "Z")), class = "data.frame",
row.names = c(NA, -4L))