Моя задача - написать функцию, которая предназначена для вычисления логарифмов заданных переменных (vars
) в заданном наборе данных (dset
) уровнями объявленной переменной (byvar
). Если минимум заданной переменной для заданного уровня byvar
больше 0, вычисляется простой натуральный логарифм. В противном случае новое значение данной переменной для данного сегмента рассчитывается как:Петля для преобразования журнала
new.value = log(old.value + 1 + abs(min.value.of.given.var.for.given.level)
Для того, чтобы достичь этого, я написал такой код (для воспроизводимой примера):
set.seed(1234567)
data(iris)
iris$random <- rnorm(nrow(iris), 0, 1)
log.vars <- function(dset, vars, byvar, verbose = F){
# a loop by levels of "byvar"
for(i in 1:length(unique(dset[[byvar]]))){
if(verbose == T){
print(paste0("------ level=", unique(dset[[byvar]])[i], "----"))
}
# a loop by variables in "vars"
for(j in 1:length(vars)){
min.var <- min(dset[[vars[j]]][dset[[byvar]] == unique(dset[[byvar]])[i]])
# if minimum of a given variable for a given level is greater than 0 then
# calculate its logarithm;
# otherwise, add to its value 1 and the mode of its minimum and calculate
# its logarithm
dset[[paste0("ln_", vars[j])]][dset[[byvar]] == unique(dset[[byvar]])[i]] <-
if(min.var > 0){
log(dset[[vars[j]]][dset[[byvar]] == unique(dset[[byvar]])[i]])
} else{
log(dset[[vars[j]]][dset[[byvar]] == unique(dset[[byvar]])[i]] + 1 +
abs(min.var))
}
}
}
return(dset)
}
iris2 <- log.vars(dset = iris,
vars = c("Sepal.Length", "random", "Sepal.Width"),
byvar = "Species",
verbose = T)
head(iris2)
Он работает , однако, существует четкая проблема с его читабельностью. Кроме того, мне интересно, можно ли повысить его производительность. И последнее, но не менее важное: цель состоит в том, чтобы сохранить порядок наблюдений в наборе данных. Любой вид помощи/предложения будут оценены
Учитывая, что он работает, и вы просто ищете улучшения для удобства чтения и, возможно, производительности, на самом деле это более подходящий вопрос для нашего сайта-пользователя CodeReview SE. –