2016-09-17 2 views
-2

Я пытаюсь создать функцию, которая позволяет преобразовать выбранные столбцы кадра данных в категориальный тип данных (коэффициент) перед запуском регрессионного анализа.R - Получение столбца Dataframe из строки

Вопрос: как я нарезаю конкретный столбец из фрейма данных, используя строку (символ).

Пример:

strColumnNames <- "Admit,Rank" 
    strDelimiter <- "," 
    strSplittedColumnNames <- strsplit(strColumnNames, strDelimiter) 
    for(strColName in strSplittedColumnNames[[1]]){ 
    dfData$as.name(strColName) <- factor(dfData$get(strColName)) 
    } 

Пробовал:

dfData$as.name() 
dfData$get(as.name()) 
dfData$get() 

Error Msg: Ошибка: попытка применить, не являющуюся функцией

Любая помощь будет принята с благодарностью! Спасибо!!!

+0

Я не знал про тик и спасибо за руководство. Кажется, что тик очень важен для пользователей - здесь довольно страшно. – AiRiFiEd

ответ

1

Вам нужно изменить

dfData$as.name(strColName) <- factor(dfData$get(strColName)) 

в

dfData[[strColName]] <- factor(dfData[[strColName]]) 

Вы можете прочитать ?"[[" больше.

В вашем случае имена столбцов генерируются программируемо, [[]] - единственный способ пойти. Может быть, этот пример будет достаточно ясно, чтобы проиллюстрировать эту проблему из $:

dat <- data.frame(x = 1:5, y = 2:6) 
z <- "x" 

dat$z 
# [1] NULL 

dat[[z]] 
# [1] 1 2 3 4 5 

Что касается другого ответа

apply определенно не работает, потому что функция установки является as.factor или factor. apply всегда работает на матрице (если вы его подаете в кадр данных, он сначала преобразует его в матрицу) и возвращает матрицу, в то время как вы не можете иметь факторный класс данных в матрице. Рассмотрим этот пример:

x <- data.frame(x1 = letters[1:4], x2 = LETTERS[1:4], x3 = 1:4, stringsAsFactors = FALSE) 
x[, 1:2] <- apply(x[, 1:2], 2, as.factor) 

str(x) 
#'data.frame': 4 obs. of 3 variables: 
# $ x1: chr "a" "b" "c" "d" 
# $ x2: chr "A" "B" "C" "D" 
# $ x3: int 1 2 3 4 

Обратите внимание: у вас все еще есть переменная символа, а не фактор. Как я уже сказал, мы должны использовать lapply:

x[1:2] <- lapply(x[1:2], as.factor) 

str(x) 
#'data.frame': 4 obs. of 3 variables: 
# $ x1: Factor w/ 4 levels "a","b","c","d": 1 2 3 4 
# $ x2: Factor w/ 4 levels "A","B","C","D": 1 2 3 4 
# $ x3: int 1 2 3 4 

Теперь мы видим класс фактор в x1 и x2.

Использование apply для фрейма данных никогда не является хорошей идеей. Если читать исходный код apply:

dl <- length(dim(X)) 
    if (is.object(X)) 
    X <- if (dl == 2L) 
     as.matrix(X) 
    else as.array(X) 

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

apply же написано в R не C, с помощью обычного for цикла:

for (i in 1L:d2) { 
     tmp <- forceAndCall(1, FUN, newX[, i], ...) 
     if (!is.null(tmp)) 
      ans[[i]] <- tmp 

так это не лучше, чем явного for цикла вы пишете сами.

0

Я использовал бы другой способ.

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

factorCols <- c("Admit", "Rank") 

Затем извлечь эти столбцы индекса:

myCols <- which(names(dfData) %in% factorCols) 

Наконец, использование применяется для изменения этих столбцов факторов:

dfData[,myCols] <- lapply(dfData[,myCols],as.factor) 
+0

hey greghk, есть ли какая-то причина выбора этого метода против предложенного Чжэюань? Спасибо! – AiRiFiEd

+0

@ ZheyuanLi вы правы, но в будущем будет лучше воспроизводить. Я хочу сказать, что код можно было бы сделать более кратким и понятным, используя функцию * apply, а не цикл for – greghk

+0

@ZheyuanLi. Я отредактировал, чтобы отразить, что вы написали о lapply – greghk

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