2016-01-24 1 views
1

Я хочу, чтобы произвести фрейм данных с колоннами для:R создать кадр данных с указанием всех уровней факторов - лучший способ сделать это?

  1. Названия каждого фактора из другого кадра данных
  2. Каждого уровня каждого фактора
  3. Соответствующий номер уровня.

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

mydata <- iris 

#Get vector of column types 
type <- sapply(mydata,class) 
# Filter out just the ones that are factors 
factors = type[type=="factor"] 
# Allocate a vector to hold 1 data frame per factor 
listOfFactors <- vector(mode = "list", length = length(factors)) 

# For each factor, list all the levels of that factor, and the level number 
for (j in 1:length(factors)) { 
    cur_colname <- names(factors[j]) 
    cur_colnum <- which(colnames(mydata)==cur_colname) 
    cur_nlevels <- nlevels(mydata[,cur_colnum]) 
    listOfFactors[[j]] <- data.frame(VarName=character(cur_nlevels), 
            Level=character(cur_nlevels), 
            Number=integer(cur_nlevels), 
            stringsAsFactors=FALSE 
            ) 
    for (i in 1:cur_nlevels) { 
      cur_level <- levels(mydata[,cur_colnum])[i] 
     listOfFactors[[j]]$VarName[i] <- cur_colname 
     listOfFactors[[j]]$Level[i] <- cur_level 
     listOfFactors[[j]]$Number[i] <- i 
    } 
} 

allfactorlevels <- do.call("rbind", listOfFactors) 
+0

Посмотрите expand.grid. – Mist

ответ

2

Основная проблема с кодом заключается в том, что вы не используете векторизованные операции. Это может быть сложно при переходе с других языков, но for-loops почти никогда не отвечают в R, особенно когда вы используете их для доступа к элементам векторного/списка/данных по одному за раз. Я сохранил первую часть вашего кода, а затем сделал (много) более consise подход в получении вывода.

type <- sapply(mydata,class) 
factors = type[type=="factor"] 

Теперь я использую «lapply» перебрать имен столбцов факторов. Это означает, что я могу использовать эти имена для доступа к исходному фреймворку данных и извлечения необходимой нам информации.

output <- lapply(names(factors),function(x){ 
    res <- data.frame(VarName=x, 
        Level=levels(mydata[,x]), 
        Number=1:nlevels(mydata[,x])) 
    return(res) 
}) 

Создание dataframe затем легко:

do.call(rbind, output) 
+0

Является ли объект 'res' каким-то локальным для определения функции? – user667489

Смежные вопросы