Вы все еще можете использовать table
, используя трюк.
Некоторые примеры данных:
set.seed(2)
m <- matrix(sample(c('-','+','0'),size=39,replace=TRUE,prob=c(0.45,0.45,0.1)), nrow=3)
m
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
# [1,] "+" "+" "+" "-" "-" "-" "+" "+" "+" "+" "+" "-" "-"
# [2,] "-" "0" "-" "-" "+" "0" "+" "-" "-" "0" "+" "-" "+"
# [3,] "-" "0" "-" "+" "+" "+" "-" "+" "+" "+" "-" "-" "-"
Трюк состоит в том, чтобы добавить все значения , а затем вычесть 1из таблицы:
apply(m, 1, function(a) table(c('-','+','0',a))-1L)
# [,1] [,2] [,3]
# - 5 6 6
# + 8 4 6
# 0 0 3 1
Поскольку оно транспонировано, некоторые предпочитают, чтобы оно оставалось релевантным для строки:
t(apply(m, 1, function(a) table(c('-','+','0',a))-1))
# - + 0
# [1,] 5 8 0
# [2,] 6 4 3
# [3,] 6 6 1
Примечание: apply
вернет matrix
, если итолько если все строки возвращают объект одинакового размера.В этом случае, поскольку мы знаем все возможные входные значения, то с помощью нашего трюка table
мы гарантируем, что у нас всегда будет integer
векторов длины 3. Если есть что-то еще, то это будетвозвращается как рваный list
.
В особом случае, если вы также хотите узнать число NA
с, вам также нужно указать table
, чтобы включить их в итоговые значения:
t(apply(m, 1, function(a) table(c('-','+','0',a,NA),useNA='always')-1L))
# - + 0 <NA>
# [1,] 5 8 0 0
# [2,] 6 4 3 0
# [3,] 6 6 1 0
m[1,2] <- NA
t(apply(m, 1, function(a) table(c('-','+','0',a,NA),useNA='always')-1L))
# - + 0 <NA>
# [1,] 5 7 0 1
# [2,] 6 4 3 0
# [3,] 6 6 1 0
(Порядок добавления «известных значений» не важен, как вы можете видеть здесь.)