将数据框中多个列的类从factor更改为numeric
将大量列从因子更改为数值的最快/最佳方法是什么 我使用了以下代码,但它似乎已对我的数据进行了重新排序将数据框中多个列的类从factor更改为numeric,r,R,将大量列从因子更改为数值的最快/最佳方法是什么 我使用了以下代码,但它似乎已对我的数据进行了重新排序 > 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 Can
> 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*
>头部(统计数据[,1:2])
rk团队
华盛顿首都*
2圣何塞鲨鱼*
3芝加哥黑鹰队*
4只凤凰狼*
5个新泽西魔鬼*
6温哥华加努克*
对于(c中的i(1,3:ncol(stats))){
统计数字[我]头(统计数字[1:2])
rk团队
12华盛顿首都*
2.13圣何塞鲨鱼*
3 24芝加哥黑鹰队*
4 26只凤凰狼*
527新泽西魔鬼队*
6 28温哥华加努克*
除了将每一列命名为中的外,最好的方法是什么:
df$colname <- as.numeric(ds$colname)
df$colname将因子更改为数值时必须小心。下面是一行代码,可以将一组列从因子更改为数值。我在这里假设要更改为数值的列分别为1、3、4和5。您可以相应地进行更改
cols = c(1, 3, 4, 5);
df[,cols] = apply(df[,cols], 2, function(x) as.numeric(as.character(x)));
根据Ramnath的回答,您正在经历的行为是由于as.numeric(x)
返回R级别的系数x
的内部数字表示。如果您希望保留系数级别的数字(而不是其内部表示),根据Ramnath的示例,首先需要通过as.character()
转换为字符
您的for
循环与apply
调用一样合理,并且可能更易于理解代码的意图。只需更改此行:
stats[,i] <- as.numeric(stats[,i])
stats[,i]我认为您的循环不起作用
如果您仍然不想使用循环,这里是使用lappy
的解决方案:
factorToNumeric <- function(f) as.numeric(levels(f))[as.integer(f)]
cols <- c(1, 3:ncol(stats))
stats[cols] <- lapply(stats[cols], factorToNumeric)
应该做你想做的。这可以在一行中完成,不需要循环,无论是for循环还是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)
#测试数据
Dflapply就是为此而设计的
unfactorize<-c("colA","colB")
df[,unfactorize]<-lapply(unfactorize, function(x) as.numeric(as.character(df[,x])))
unfactorize我在使用apply()
调用将所有列转换为数字时遇到问题:
apply(data, 2, as.numeric)
问题是,有些字符串中有逗号,例如“1024.63”而不是“1024.63”,而R不喜欢这种格式化数字的方式。因此,我删除了它们,然后以.numeric()的形式运行:
请注意,这需要加载stringr包。我想指出,如果在任何列中都有NAs,那么简单地使用下标将不起作用。如果factor中有NAs,则必须使用Ramnath提供的apply脚本
例如
但是:
返回:
> 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
我知道这个问题早就解决了,但我最近遇到了一个类似的问题,我认为我找到了一个更优雅、更实用的解决方案,尽管它需要magrittr包
library(magrittr)
cols = c(1, 3, 4, 5)
df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))
库(magrittr)
cols=c(1,3,4,5)
df[,cols]%lappy(函数(x)为数字(字符(x)))
%%
操作符用于管道和重新分配,这对于保持数据清理和转换简单非常有用。现在,list apply函数更易于阅读,只需指定要应用的函数。这对我很有用。apply()
函数尝试将df强制到矩阵,并返回NA
numeric.df我在另外两个重复的线程上发现了这个函数,并且发现它是解决这个问题的一种优雅而通用的方法。这个线程首先出现在关于这个主题的大多数搜索中,所以我在这里分享它是为了节省人们的时间。我不相信这一点,只是为了查看原始帖子和详细信息
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")
df您可以使用“varhandle”包表单CRAN中的unfactor()
函数:
library("varhandle")
my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length),
sample_id = factor(1:nrow(iris)))
my_iris <- unfactor(my_iris)
库(“varhandle”)
my_iris我喜欢这段代码,因为它非常方便:
data[] <- lapply(data, function(x) type.convert(as.character(x), as.is = TRUE)) #change all vars to their best fitting data type
data[]根据@SDahm的回答,这是我的tibble
的“最佳”解决方案:
data %<>% lapply(type.convert) %>% as.data.table()
data%%lappy(type.convert)%%>%as.data.table()
这需要dplyr
和magrittr
我在一个类似的问题上尝试了很多,并不断得到NAs。Base R有一些非常恼人的强制行为,这些行为通常在Tidyverse包中得到修复。我过去避免它们,因为我不想创建依赖项,但现在它们让生活变得更加轻松大多数时候,我甚至不想费心去找出基本的R解决方案
这是Tidyverse解决方案,它非常简单和优雅:
library(purrr)
mydf <- data.frame(
x1 = factor(c(3, 5, 4, 2, 1)),
x2 = factor(c("A", "C", "B", "D", "E")),
x3 = c(10, 8, 6, 4, 2))
map_df(mydf, as.numeric)
库(purrr)
mydf以下是一些dplyr
选项:
# by column type:
df %>%
mutate_if(is.factor, ~as.numeric(as.character(.)))
# by specific columns:
df %>%
mutate_at(vars(x, y, z), ~as.numeric(as.character(.)))
# all columns:
df %>%
mutate_all(~as.numeric(as.character(.)))
df$colname这将无法正常工作。例如:xapply在这些情况下工作得非常好。我的代码中的错误是使用margin=1,而不是2,因为函数需要按列应用。我已经相应地编辑了我的答案。现在它可以工作了。但我认为它可以在没有apply
的情况下完成。请检查我的编辑…或Joris answ不需要在解决方案中使用unlist
和as.character
转换,因为apply
将df[,cols]
转换为character
soapply(df[,cols],2,函数(x)as.numeric(x))
也可以。@Ramnath,为什么要使用=
?为什么不使用不需要任何类型的循环。只需使用索引和取消列表().Edit:我添加了一个答案来说明这一点。这种方法只在这种特定情况下有效。我试图用它将列转换为因子,但它不起作用。sapply
或mutate\u if
似乎是更普遍适用的解决方案。@Leo愿意扩展一下,因为我知道事实上这是有效的。这是完全相同的解决方案n与Ramnath下面的一样,除了他使用apply
来运行循环外,OP显式地使用了for
循环。事实上,所有投票率较高的答案都使用as.numeric(as.character())
习惯用法。是的,它可以将多列类更改为numeric
,但它不能
library(magrittr)
cols = c(1, 3, 4, 5)
df[,cols] %<>% lapply(function(x) as.numeric(as.character(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")
library("varhandle")
my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length),
sample_id = factor(1:nrow(iris)))
my_iris <- unfactor(my_iris)
data[] <- lapply(data, function(x) type.convert(as.character(x), as.is = TRUE)) #change all vars to their best fitting data type
data %<>% lapply(type.convert) %>% as.data.table()
library(purrr)
mydf <- data.frame(
x1 = factor(c(3, 5, 4, 2, 1)),
x2 = factor(c("A", "C", "B", "D", "E")),
x3 = c(10, 8, 6, 4, 2))
map_df(mydf, as.numeric)
# by column type:
df %>%
mutate_if(is.factor, ~as.numeric(as.character(.)))
# by specific columns:
df %>%
mutate_at(vars(x, y, z), ~as.numeric(as.character(.)))
# all columns:
df %>%
mutate_all(~as.numeric(as.character(.)))