R: извлекать последовательность частот (таблицы сопряженности) из возрастающих частей вектора - PullRequest
0 голосов
/ 29 мая 2018

У меня есть вектор V с n элементами, каждый элемент может быть целым числом от 1 до N. Учитывая этот вектор, я хотел бы построить матрицу N × n W, в которой столбец i содержит частоты целых чисел от 1и N, как они появляются в подвекторе V [1: i].

Например, предположим, что N = 5 и n = 7, а V = c (3,1,4,1,2,1,4).Тогда моя матрица W будет иметь элементы

0,1,1,2,2,3,3  
0,0,0,0,1,1,1  
1,1,1,1,1,1,1  
0,0,1,1,1,1,2  
0,0,0,0,0,0,0  

, поскольку целое число 1 (первая строка) появляется: 0 раз в V [1], один раз в V [1: 2], один раз в V [1: 3]дважды в V [1: 4], дважды в V [1: 5], три раза в V [1: 6], три раза в V [1: 7] и т. д.

Я мог бы этос циклом for, используя table и factor, например:

N <- 5
n <- 7
V <- c(3,1,4,1,2,1,4)
W <- matrix(NA,N,n)

for(i in 1:n){
    W[,i] <- as.vector(table(factor(V[1:i], levels=1:N)))
}

, что фактически дает

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    0    1    1    2    2    3    3
[2,]    0    0    0    0    1    1    1
[3,]    1    1    1    1    1    1    1
[4,]    0    0    1    1    1    1    2
[5,]    0    0    0    0    0    0    0

Но мне интересно, есть ли какой-нибудь более умный, более быстрый способв нем не используется цикл for: мои N и n имеют порядок 100 или 1000.

Любое другое понимание для улучшения кода выше также приветствуется (мои знания R по-прежнему очень просты).

Ура!

1 Ответ

0 голосов
/ 29 мая 2018

Один вариант с основанием R:

V <- c(3, 1, 4, 1, 2, 1, 4)
N <- 5

sapply(seq_along(V), 
       function(i) sapply(seq_len(N), function(j) sum(V[seq_len(i)] == j)))

#      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,]    0    1    1    2    2    3    3
# [2,]    0    0    0    0    1    1    1
# [3,]    1    1    1    1    1    1    1
# [4,]    0    0    1    1    1    1    2
# [5,]    0    0    0    0    0    0    0

Как это работает
seq_along(V): Это оболочка для 1:length(V), т.е. она возвращает вектор, которыйпоследовательность от 1 до длины вашего вектора V. Если вы уверены, что ваш вектор V не пустой, вы также можете использовать 1:length(V) здесь (или 1:n в вашем случае)

seq_len(N):Похоже на seq_along, но возвращает 1:N.Если вы уверены, что N неотрицательна, вы также можете использовать 1:N.

sapply: это функция из удивительной *apply -семейства.Он берет вектор или список и применяет функцию, которая указана для каждого элемента этого вектора / списка.sapply возвращает простую структуру, которая в нашем случае является вектором для внутреннего вызова sapply и матрицей для полного вызова.

sum(V[seq_len(i)] == j): Здесь мы суммируем по логическому вектору, который сравнивает каждый «субвектор» V[1:i] с j.Суммируя по логическому вектору, мы просто считаем число TRUE с.

...