Я считаю, что это то, что вы искали, хороший выразительный векторизованный R-код.Здесь нет циклов, даже * не применяются команды family или plyr.Вы можете сделать множество вещей, чтобы сделать его более гибким, но векторизация ядра, использующая rep
, и одиночные вызовы на случайные расстояния довольно важны.Я понятия не имею, почему был пункт if
для измерений поп.Вы должны обращаться с этим по-другому, потому что это не сделано до конца.
year = 2004
survival_prob = 0.01
male_prob = 0.5
# you don't do anything in your for loop or save any of the results if the age is
# less than 4. I'm going to just remove that from colonies on the assumption that it's
# larger than posted and comes from a file that you won't change. Where I edit
# colonies you might want to work with a copy.
colonies <- colonies[colonies$Age >= 4,]
# only Present selection of colonies is ever used in this code so you could also stop
# repeatedly selecting... this one I'm imagining you might make a copy of, something
# like coloniesP in your real code. In general, you want as little going on in a
# loop and as little repeating yourself as possible. Note, this might be memory
# intensive if colonies is actually very large. Feel free to going back to selecting
# since it would happen much less frequently in the new code anyway.
Present <- colonies$Timecount == year
colonies <- colonies[Present,]
# no difference up to size, then it all is
app <- sum(colonies$Age >= 4 & colonies$Age < 10) * 1000 * survival_prob
app2 <- sum(colonies$Age >= 10 & colonies$Age < 15) * 10000 * survival_prob
app3 <- sum(colonies$Age >= 15 & colonies$Age <= 20) * 100000 * survival_prob
size <- app + app2 + app3
#note that ifelse can be used to declare alates as vectors
alates <- ifelse(colonies$Age >= 4 & colonies$Age < 10, 1000, 100000)
alates <- ifelse(colonies$Age >= 10 & colonies$Age < 15, 10000, alates)
# as a consequence, more stuff can be vectorized
indiv <- alates * survival_prob
# we can do some cool stuff with rep to continue vectorizing
# (round when done if you must)
X_temp <- rep(colonies$X, indiv)
Y_temp <- rep(coloines$Y, indiv)
#Initialize two coordinate variables based on the established (or existing) colonies... now as vectors of the entire data frame size
distance <- rexp(size,rate=1/200)
theta <- runif(size, 0, 2*pi)
C <- cos(theta)
S <- sin(theta)
#XY coords (meters) using polar coordinate transformations
X <- X_temp + S * distance
Y <- Y_temp + C * distance
pop <- data.frame(X,Y)
pop$Sex <- rbinom(size,1,male_prob)
pop$ID <- 1:dim(pop)[1]
# now round... once
pop$X <- round(pop$X,2)
pop$Y <- round(pop$Y,2)
Кроме того, вы можете заметить, что даже если это не может быть векторизация, есть решение вашей проблемы с назначением значенийв поп это очень просто .. не надо.Просто используйте lapply для функции, которая возвращает data.frame, и связывайте список объектов data.frame впоследствии.