сохраненные значения в пользовательской функции - PullRequest
2 голосов
/ 24 апреля 2010

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

EDIT

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

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) и создаю постоянный объект, который затем вставляю в свою функцию.

Ответы [ 4 ]

1 голос
/ 25 апреля 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)
}
1 голос
/ 24 апреля 2010

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

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

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]]]

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

1 голос
/ 24 апреля 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)
0 голосов
/ 24 апреля 2010

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

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

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