2016-02-23 3 views
0

Я обычно являюсь пользователем клена, который в настоящее время работает с R, и у меня есть проблема с правильной индексацией переменных.Индексирующие переменные в R

Скажем, я хочу определить 2 вектора, v1 и v2, и я хочу вызвать n-й элемент в v1. В клене это легко сделать: v [1]: = некоторый вектор,

и n-й элемент затем вызывается командой v [1] [n]. Как это можно сделать в R? Фактическая проблема заключается в следующем:

У меня есть последовательность M (скажем, длина 10, проиндексированная k) имитируемых переменных негбина. Для каждой из этих имитируемых переменных я хочу построить вектор X длины M [k] с элементами, заданными некоторой формулой. Таким образом, я должен получить 10 разных векторов, каждая из которых имеет разную длину. Мой неверный код выглядит как появится этот

sims<-10 
M<-rnegbin(sims, eks_2016_kasko*exp(-2.17173), 840.1746) 
for(k in 1:sims){ 
       x[k]<-rep(NA,M[k]) 
       X[k]<-rep(NA,M[k]) 
for(i in 1:M[k]){x[k][i]<-runif(1,min=0,max=1) 
        if(x[k][i]>=0 & x[i]<=0.1056379){ 
        X[k][i]<-rlnorm(1, 6.228244, 0.3565041)} 
    else{ 
    X[k][i]<-rlnorm(1, 8.910837, 1.1890874) 
    } 
} 
} 

Ошибка быть, что х [к] не является допустимым именем для переменной. Любой способ сделать эту работу?

Большого спасибо :)

+0

'[' используется для индексирования, поэтому 'x [i]' извлекает элемент 'i'th из вектора' x'. Поэтому 'x [k]' действительно не является допустимым именем переменной. Для того, чтобы помочь вам, очень полезен [воспроизводимый пример] (http://stackoverflow.com/q/5963269/4303162). Кажется, что ваш примерный код будет воспроизводимым, если вы предоставили 'eks_2016_kasko' и' rnegbin() 'или' M'. – Stibu

+0

Получает ли 'rnegbin()' пакет 'MASS'? – Stibu

+0

eks_2016_kasko = 486689.1. Правильно, rnegbin действительно из пакета MASS :) – user128836

ответ

1

Я редактировал свой R сценарий немного, чтобы заставить его работать и сделать его воспроизводит. Для этого я должен был предположить, что eks_2016_kasko было целочисленным значением 10.

require(MASS) 
sims<-10 

# Because you R is not zero indexed add one 
M<-rnegbin(sims, 10*exp(-2.17173), 840.1746) + 1 

# Create a list 
x <- list() 
X <- list() 
for(k in 1:sims){ 
    x[[k]]<-rep(NA,M[k]) 
    X[[k]]<-rep(NA,M[k]) 
    for(i in 1:M[k]){ 
     x[[k]][i]<-runif(1,min=0,max=1) 
    if(x[[k]][i]>=0 & x[[k]][i]<=0.1056379){ 
     X[[k]][i]<-rlnorm(1, 6.228244, 0.3565041)} 
    else{ 
     X[[k]][i]<-rlnorm(1, 8.910837, 1.1890874) 
    } 
    } 

Это будет работать, и я думаю, это то, что вы пытались сделать, НО не большой R-код. Я настоятельно рекомендую использовать lapply family вместо циклов for, научившись использовать data.table и параллелизацию, если вам нужно получать вещи в масштабе. Кроме того, если вы хотите больше узнать об индексации в R и подмножестве, Hadley Wickham имеет исчерпывающий разброс here.

Надеюсь, это поможет!

1

Позвольте мне начать с несколько замечаний, а затем показать вам, как ваша проблема может быть решена с помощью Р.

  • В R нет большую часть времени нет необходимости использовать for петлю для того, для назначения нескольким значениям вектору. Так, например, чтобы заполнить вектор длиной 100 с равномерно распределенными случайными величинами, вы делаете что-то вроде:

    set.seed(1234) 
    x1 <- rep(NA, 100) 
    for (i in 1:100) { 
        x1[i] <- runif(1, 0, 1) 
    } 
    

    (set.seed() используется для установки случайных семян, так что вы получите тот же результат каждый раз.) это гораздо проще (и гораздо быстрее), чтобы сделать это вместо:

    x2 <- runif(100, 0, 1) 
    identical(x1, x2) 
    ## [1] TRUE 
    

    Как вы видите, результаты идентичны.

  • Причина, по которой x[k]<-rep(NA,M[k]) не работает в том, что на самом деле x[k] не является допустимым именем переменной в R. [ используется для индексации, поэтому x[k] извлекает элемент k из вектора x. Поскольку вы пытаетесь присвоить вектор длины длиной более 1 для одного элемента, вы получите сообщение об ошибке. То, что вы, вероятно, хотите использовать, - это список, как вы увидите в приведенном ниже примере.

Итак, вот код, который я использовал бы вместо того, что вы предлагали в своем посте.Обратите внимание, что я не уверен, что правильно понял, что вы намереваетесь делать, поэтому я также опишу ниже, что делает код. Дайте мне знать, если это соответствует вашим намерениям.

# define M 
library(MASS) 
eks_2016_kasko <- 486689.1 
sims<-10 
M<-rnegbin(sims, eks_2016_kasko*exp(-2.17173), 840.1746) 

# define the function that calculates X for a single value from M 
calculate_X <- function(m) { 
    x <- runif(m, min=0,max=1) 
    X <- ifelse(x > 0.1056379, rlnorm(m, 6.228244, 0.3565041), 
       rlnorm(m, 8.910837, 1.1890874)) 
} 
# apply that function to each element of M 
X <- lapply(M, calculate_X) 

Как вы можете видеть, в этом решении нет петель. Начну объяснить в конце:

  • lapply используется для применения функции (calculate_X) к каждому элементу списка или вектора (здесь вектор M). Он возвращает список. Таким образом, вы можете получить, например. третий из векторов с X[[3]] (обратите внимание, что [[ используется для извлечения элементов из списка). И содержимое X[[3]] будет результатом calculate_X(M[3]).

  • Функция calculate_X() выполняет следующие действия: Это создает вектор m равномерно распределенных случайных величин (помните, что m пробегает элементы M) и магазинов, которые в x. Затем он создает вектор X, который содержит логарифмически распределенные случайные величины. Параметры распределения зависят от значения x.

+0

Огромное вам обоим вас :) Получил его все отсортировано. – user128836

+1

На самом деле, ваш код дает векторы правильной длины, но каждая запись принимает только одно из двух разных значений, например. для X [[3]] [3] = X [[3]] [9] = X [[3]] [550] = 42775,2. Таким образом, похоже, что он использует ту же симуляцию снова и снова. – user128836

+0

Вы правы! Во втором вызове 'rlnorm' я написал' 1' вместо 'm'. Теперь это исправлено. Извини за это! – Stibu

Смежные вопросы