Измените класс с factor на numeric для многих столбцов во фрейме данных



какой самый быстрый/лучший способ изменить большое количество столбцов с числовыми от фактора?



я использовал следующий код, но он, кажется, переупорядочил мои данные.



> head(stats[,1:2])
rk team
1 1 Washington Capitals*
2 2 San Jose Sharks*
3 3 Chicago Blackhawks*
4 4 Phoenix Coyotes*
5 5 New Jersey Devils*
6 6 Vancouver Canucks*

for(i in c(1,3:ncol(stats))) {
stats[,i] <- as.numeric(stats[,i])
}

> head(stats[,1:2])
rk team
1 2 Washington Capitals*
2 13 San Jose Sharks*
3 24 Chicago Blackhawks*
4 26 Phoenix Coyotes*
5 27 New Jersey Devils*
6 28 Vancouver Canucks*


каков наилучший способ, не называя каждый столбец, как в:



df$colname <- as.numeric(ds$colname)
491   11  
r

11 ответов:

в дополнение к ответу Рамната, поведение, которое вы испытываете, связано с as.numeric(x) возвращает внутреннее числовое представление фактора x на уровне Р. Если вы хотите сохранить числа, которые являются уровнями фактора (а не их внутренним представлением), вам нужно преобразовать в символ через as.character() во-первых, согласно примеру Рамната.

код for цикл так же разумно, как apply вызов и может быть немного более читаемым, чтобы в чем смысл этого кодекса. Просто измените эту строку:

stats[,i] <- as.numeric(stats[,i])

читать

stats[,i] <- as.numeric(as.character(stats[,i]))

это FAQ 7.10 в R FAQ.

HTH

вы должны быть осторожны при изменении факторов в числовые. Вот строка кода, которая изменит набор столбцов с фактора на числовой. Я предполагаю, что столбцы, которые будут изменены на числовые, равны 1, 3, 4 и 5 соответственно. Вы можете изменить его соответствующим образом

cols = c(1, 3, 4, 5);    
df[,cols] = apply(df[,cols], 2, function(x) as.numeric(as.character(x)));

Это можно сделать в одной строке, нет необходимости в цикле, будь то for-loop или apply. Вместо этого используйте unlist ():

# testdata
Df <- data.frame(
  x = as.factor(sample(1:5,30,r=TRUE)),
  y = as.factor(sample(1:5,30,r=TRUE)),
  z = as.factor(sample(1:5,30,r=TRUE)),
  w = as.factor(sample(1:5,30,r=TRUE))
)
##

Df[,c("y","w")] <- as.numeric(as.character(unlist(Df[,c("y","w")])))

str(Df)

изменить : для вашего кода, это выглядит так :

id <- c(1,3:ncol(stats))) 
stats[,id] <- as.numeric(as.character(unlist(stats[,id])))

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

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

library(magrittr)
cols = c(1, 3, 4, 5)
df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))

The %<>% оператор трубы и переназначения, что очень полезно для поддержания очистки данных и преобразования просто. Теперь список применить функцию гораздо легче читать, только указав функцию, которую вы хотите применить.

думаю, что ucfagls нашел почему ваш цикл не работает.

в случае, если вы все еще не хотите использовать цикл вот решение с lapply:

factorToNumeric <- function(f) as.numeric(levels(f))[as.integer(f)] 
cols <- c(1, 3:ncol(stats))
stats[cols] <- lapply(stats[cols], factorToNumeric)

правка. Я нашел более простое решение. Кажется, что as.matrix преобразовать в символ. Так что

stats[cols] <- as.numeric(as.matrix(stats[cols]))

должны делать то, что вы хотите.

lapply в значительной степени предназначен для этого

unfactorize<-c("colA","colB")
df[,unfactorize]<-lapply(unfactorize, function(x) as.numeric(as.character(df[,x])))

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

df <- data.frame(x = 1:10,
                 y = rep(1:2, 5),
                 k = rnorm(10, 5,2),
                 z = rep(c(2010, 2012, 2011, 2010, 1999), 2),
                 j = c(rep(c("a", "b", "c"), 3), "d"))

convert.magic <- function(obj, type){
  FUN1 <- switch(type,
                 character = as.character,
                 numeric = as.numeric,
                 factor = as.factor)
  out <- lapply(obj, FUN1)
  as.data.frame(out)
}

str(df)
str(convert.magic(df, "character"))
str(convert.magic(df, "factor"))
df[, c("x", "y")] <- convert.magic(df[, c("x", "y")], "factor")

Я хотел бы отметить, что если у вас есть NAs в любом столбце, просто с помощью индексов не будет работать. Если в факторе есть NAs, вы должны использовать сценарий apply, предоставленный Ramnath.

например.

Df <- data.frame(
  x = c(NA,as.factor(sample(1:5,30,r=T))),
  y = c(NA,as.factor(sample(1:5,30,r=T))),
  z = c(NA,as.factor(sample(1:5,30,r=T))),
  w = c(NA,as.factor(sample(1:5,30,r=T)))
)

Df[,c(1:4)] <- as.numeric(as.character(Df[,c(1:4)]))

возвращает следующее:

Warning message:
NAs introduced by coercion 

    > head(Df)
       x  y  z  w
    1 NA NA NA NA
    2 NA NA NA NA
    3 NA NA NA NA
    4 NA NA NA NA
    5 NA NA NA NA
    6 NA NA NA NA

но:

Df[,c(1:4)]= apply(Df[,c(1:4)], 2, function(x) as.numeric(as.character(x)))

возвращает:

> head(Df)
   x  y  z  w
1 NA NA NA NA
2  2  3  4  1
3  1  5  3  4
4  2  3  4  1
5  5  3  5  5
6  4  2  4  4

у меня были проблемы с преобразованием всех столбцов в числовые с помощью apply() звоните:

apply(data, 2, as.numeric)

проблема оказывается в том, что некоторые строки имели запятую в них-например, "1,024.63" вместо "1024.63" - и R не нравится этот способ форматирования чисел. Поэтому я удалил их, а затем побежал as.numeric():

data = as.data.frame(apply(data, 2, function(x) {
  y = str_replace_all(x, ",", "") #remove commas
  return(as.numeric(y)) #then convert
}))

обратите внимание, что для этого требуется загрузить пакет stringr.

вот что сработало для меня. Элемент apply() функция пытается принудить df к Матрице и возвращает NA.

numeric.df <- as.data.frame(sapply(df, 2, as.numeric))

можно использовать unfactor() функция из формы пакета "varhandle" CRAN:

library("varhandle")

my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length),
                      sample_id = factor(1:nrow(iris)))

my_iris <- unfactor(my_iris)

Comments

    Ничего не найдено.