сохраненные значения в пользовательской функции

Моя программа берет data.frame и обрабатывает числа. В какой-то момент значения из j-го столбца умножаются на предопределенное значение, которое зависит от имени столбца (название вида, фактически - это экологический индекс). До сих пор я предоставлял эти значения через второй data.frame, сопоставляя имена столбцов. Каким был бы эффективный способ интеграции значений фиксированных переменных в функцию? Я хотел бы, чтобы моя программа была как можно более переносимой, без необходимости во втором файле data.frame.

ИЗМЕНИТЬ

Это функция. Я пытаюсь улучшить вторую строку (индекс ‹-read.table...), чтобы она не зависела от внешнего источника.

macroIndex <- function(obj, index) {
    index <- read.table("conv.csv", header=T, dec=",")
    a <- c()
    b <- names(obj)
    for (i in 2:length(obj)) {
        obj[i] <- obj[i] * index[which(index==b[i]), 2]
    }
    obj
}

Еще одно решение, которое я попробовал, хотя оно может показаться не очень красивым, но оно выполняет свою работу. Я использую dput(index) и создаю постоянный объект, который затем вставляю в свою функцию.


person Roman Luštrik    schedule 24.04.2010    source источник
comment
Моей первой мыслью, как интегрировать все это в компактную форму торпеды Neato, был небольшой пакет. В конце концов, это то, что я могу сделать.   -  person Roman Luštrik    schedule 25.04.2010
comment
Это может быть самым элегантным решением, так как вы можете включить свой фрейм данных индекса в пакет, просто не забудьте задокументировать его.   -  person PaulHurleyuk    schedule 25.04.2010


Ответы (4)


Что ж, вам нужно сопоставить имена ваших столбцов с другим значением, поэтому вам нужно как-то их сохранить. Я бы сказал, что именованный список был бы более подходящей структурой данных, хотя, в конце концов, это не имеет большого значения.

Вот некоторые примеры данных:

df <- data.frame(a=1:5, b=2:6)
mapping <- list(a=3, b=4)

Вот простой пример использования списка:

for(i in 1:ncol(df)) df[,i] <- df[,i] * mapping[[colnames(df)[i]]]

Что касается рекомендации Таля по использованию матрицы: это верно, если все значения в вашем фрейме данных относятся к одному типу. Если у вас смешанные типы, вам нужно придерживаться фрейма данных.

person Shane    schedule 24.04.2010
comment
Без петли: df[,] <- lapply(names(df), function(i) df[[i]] * mapping[[i]]) - person Marek; 25.04.2010

Вы можете использовать лексическую область видимости R, чтобы определить функцию function_maker, которая возвращает желаемую функцию func. Код для создания вектора отображения вызывается только при вызове function_maker, а не при вызове func. mapping также принадлежит func, поскольку другие части вашего кода не могут его изменить.

dat <- data.frame(a=c(1,2,3),b=c(3,2,0),c=c(5,6,4))

function_maker <- function(){
    mapping <- c(a=4,b=2,c=5)
    function(df){
        for(i in 1:ncol(df)) df[,i] <- df[,i] * mapping[[colnames(df)[i]]]
        return(df)
    }
}

func <- function_maker()

func(dat)
person Ian Fellows    schedule 24.04.2010

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

Что-то вроде (извините, я не на своем ПК, так что это не проверено)

macroIndex <- function(obj, index) {
  if(!exists(index)) {
    index <- data.frame(# contents of the default data frame here )
  }
  a <- c()
  b <- names(obj)
  for (i in 2:length(obj)) {
      obj[i] <- obj[i] * index[which(index==b[i]), 2]
  }
  return(obj)
}
person PaulHurleyuk    schedule 25.04.2010
comment
Это был один из вариантов, который я рассматривал. Что я пытаюсь сделать, так это заставить функцию принимать как можно меньше аргументов, чтобы ее можно было переносить на людей, которые менее осведомлены о R. Я не вижу в этом большого препятствия на данный момент, но буду продолжать это в виду. - person Roman Luštrik; 29.04.2010

1) рассмотрите возможность перехода на матрицу вместо data.frame - чтобы получить более быстрые результаты.

2) Не могли бы вы предоставить простой код, чтобы объяснить, чего вы хотите достичь?

person Tal Galili    schedule 24.04.2010
comment
Я обновил свой пост и включил функцию. Я подозреваю, что data.frames, которые будут использоваться для расчета этого экологического индекса, не вырастут настолько, чтобы вызвать проблемы со скоростью. - person Roman Luštrik; 25.04.2010