генерация случайной строки и симуляция в R - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу создать случайную строку длиной 50 из четырех символов 'e', ​​'l', 'i', 'r', которые встречаются с частотой 0.6,0.1,0.1,0.2. После создания случайной строки я хочу провести симуляцию 5000 раз и посмотреть, в какой пропорции встречается «el» в каждой симуляции. Я создал случайную строку, используя следующую команду:

x <- paste(sample( c('e','l','i','r'), 50, replace=TRUE, prob=c(0.6,0.1, 0.1, 0.2) ),collapse = '')

Но теперь я запутался, как делать симуляции 5000 раз. Я догадался, что, возможно, я мог бы использовать функцию репликации и использовать это, чтобы найти пропорцию. Но я запутался, как использовать это в этом контексте. Помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Начиная с вашего кода:

set.seed(2)
x <- paste(sample( c('e','l','i','r'), 50, replace=TRUE, prob=c(0.6,0.1, 0.1, 0.2) ),collapse = '')
x
# [1] "ereelleieeeereeileeereieeeeeleeeiieriereleeelrleei"

Мы можем легко повторить это с:

set.seed(2)
xmany <- replicate(5000, paste(sample( c('e','l','i','r'), 50, replace=TRUE, prob=c(0.6,0.1, 0.1, 0.2) ),collapse = ''))
head(xmany)
# [1] "ereelleieeeereeileeereieeeeeleeeiieriereleeelrleei"
#4#       ^                       ^           ^   ^
# [2] "eerleirlrrrireieeeeeeeeeereieeereeeilereleeeeeeeee"
#1#                                           ^
# [3] "eelieeieeeereeiiieleeeliereereelelereieeeereerreee"
#5#     ^               ^   ^        ^ ^
# [4] "eelereieeeilerereleeleeiereerelelreiereeeeleeeeeee"
#6#     ^              ^  ^         ^ ^         ^
# [5] "irrleieeeeleirleeeeeeleerilerireieieeeeeieerlleeee"
#2#             ^          ^
# [6] "reeereeeerrereirerieiliereleeeelrreleereeerereeeee"
#3#                             ^    ^   ^

Я добавил текст, чтобы выделить в каждой строке вхождения "el".

Если вам нужно количество вхождений "el" в каждой строке, то (без head для всего):

ispos <- function(a) a > 0
head( lengths(Filter(ispos, gregexpr("el", xmany))) )
# [1] 4 1 5 6 2 3

Примечание: я создал функцию ispos, потому что gregexpr будет возвращать -1, если совпадений не будет, что будет держать возвращаемый вектор длиной 1 или более. Таким образом, удаляя негативные элементы, мы получаем честное возвращение. (Я мог бы использовать regmatches(gregexpr(...),xmany), но кажется, что это намного больше работы, чем необходимо для получения количества вхождений.)

Если вам нужна таблица частот для него:

table( lengths(Filter(ispos, gregexpr("el", xmany))) )
#    0    1    2    3    4    5    6    7    8    9 
# 9701  891 1145 1241  936  459  178   69   16    1 
0 голосов
/ 06 сентября 2018

Итак, вы находите совпадение . Если вы не paste результат, это будет намного проще (и быстрее). Я бы адаптировал функцию foo, определенную в моем ответе, к связанным вопросам и ответам.

set.seed(0)

## one example sample
char_tank <- c('e','l','i','r')
char_prob <- c(0.6, 0.1, 0.1, 0.2)
x <- sample(char_tank, 50, replace = TRUE, prob = char_prob)
# [1] "i" "e" "e" "e" "l" "e" "i" "l" "r" "r" "e" "e" "e" "r" "e" "r" "e" "r" "l"
#[20] "e" "r" "l" "e" "r" "e" "e" "e" "e" "e" "i" "e" "e" "e" "e" "e" "i" "r" "r"
#[39] "e" "r" "e" "i" "r" "r" "e" "e" "r" "e" "e" "r"

## adapted from function `foo` from https://stackoverflow.com/a/51695793/4891738
## the function is shorter because you just want to find not to remove matches
count_co_occurrence <- function (xm, xs) {
  nm <- length(xm)
  ns <- length(xs)
  shift_ind <- outer(0:(ns - 1), 1:(nm - ns + 1), "+")
  d <- xm[shift_ind] == xs
  sum(.colSums(d, ns, length(d) / ns) == ns)
  }

count_co_occurrence(x, c('e', 'l'))
#[1] 1

В этом случае вы видите, что x[4:5] соответствует.


Использовать replicate + lapply / sapply / vapply просто, чтобы повторить вышеизложенное.

## just do 10 simulations as a small example
set.seed(0)
xx <- replicate(10, sample(char_tank, 50, replace = TRUE, prob = char_prob),
                simplify = FALSE)
yy <- vapply(xx, count_co_occurrence, xs = c('e', 'l'), 0L)
# [1] 1 1 4 1 2 2 4 4 5 5

Я не уверен, как бы вы определили «пропорцию» совместного появления. Это yy / (50 - (2 - 1)) в этом случае?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...