Превратите основанную на индексе l oop в основанную на имени функцию - PullRequest
1 голос
/ 19 марта 2020

У меня есть чистый фрейм данных (1500r x 297 c, названный «Данные» - очень вдохновляющий) с обоими столбцами чисел / коэффициентов. Однако, поскольку это часто имеет место, мои факторы были закодированы как числа (каждое число представляет уровень), следовательно, кадр данных заполнен цифрами c векторов. Чтобы преодолеть эту проблему, у меня также есть второй фрейм данных (VarLabels), содержащий информацию о столбцах 1-го фрейма данных (который имеет ... 297 строк, как вы могли бы представить). Там один конкретный столбец c помогает мне определить, каким должен быть класс данных в главном фрейме данных (с именем VarLabels $ TypeVar).

Я написал следующий фрагмент кода, который может быть не оптимальным, но доказанным чтобы работать до сих пор:

(NB: как вы можете видеть, для данных, помеченных «MIX», я буду sh, чтобы создать копию, имеющую одну цифру c и один фактор)

nbcol <- ncol(Data)
indexcol <- which(colnames(VarLabels) == "TypeVar")
for(i in 1:nbcol){
  if (colnames(Data)[[i]] %in% VarLabels$VarName){

    if (VarLabels[i,indexcol] == "Quant"){ 
      Data[[i]] <- as.numeric(Data[[i]])

    } else if (VarLabels[i,indexcol] == "Qual") { 
      Data[[i]] <- as.character(Data[[i]])
      Data[[i]] <- as.factor(Data[[i]])

    } else if (VarLabels[i,indexcol] == "Mix") { 
      Data <- cbind(Data, Data[[i]])
      Data[[i]] <- as.character(Data[[i]])
      Data[[i]] <- as.factor(Data[[i]])
      Data[[ncol(Data)]] <- as.numeric(Data[[ncol(Data)]])
      colnames(Data)[[ncol(Data)]] <- paste(colnames(Data)[[i]], "Num", sep = "_")

    } else {
      Data[[i]] <- as.numeric(Data[[i]])
    }
  } else {
  }  
}

Есть ли у вас более точное решение, возможно, с использованием функции для уменьшения количества строк кода / использования имен вместо индекса столбца? (что может быть опасно, если порядок изменяется в одном из двух информационных кадров) Недавно я попал в R и все еще борюсь с пользовательскими функциями.

Я читаю другие связанные темы, такие как:

Изменить все столбцы с коэффициента на число c в R

Функция для изменения класса столбцов в R в соответствии с классом другого набора данных

Преобразование типа нескольких столбцов в фрейме данных одновременно

Как получить классы всех столбцов в фрейме данных?

, но не мог применить ответы к моей собственной проблеме. Есть идеи, как все упростить? (если возможно!)

1 Ответ

2 голосов
/ 19 марта 2020

Следующая функция выполняет то, о чем спрашивает вопрос.
Она сопоставляет входные данные набора X имен столбцов с новыми типами столбцов с последовательностью операторов which/match без циклов. Приведение выполняется с помощью lapply петель.
Набор тестовых данных - это встроенный набор данных mtcars.

coerceCols <- function(X, VarLabels){
  i <- which(VarLabels$TypeVar == "Qual")
  j <- match(VarLabels$VarName[i], names(X))
  X[j] <- lapply(X[j], factor)

  i <- which(VarLabels$TypeVar == "Mix")
  j <- match(VarLabels$VarName[i], names(X))
  tmp <- X[j]
  names(tmp) <- paste(names(tmp), "Num", sep = "_")
  X[j] <- lapply(X[j], factor)

  cbind(X, tmp)
}

Data <- mtcars
VarLabels <- data.frame(VarName = names(mtcars),
                        TypeVar = c("Quant", "Mix", "Quant",
                                    "Quant", "Quant", "Quant",
                                    "Quant", "Qual", "Qual", 
                                    "Mix", "Mix"),
                        stringsAsFactors = FALSE)

coerceCols(Data, VarLabels)
...