R -apply- 将许多列从数字转换为因子
R -apply- convert many columns from numeric to factor
我需要将许多数字列转换为因子类型。
一个例子 table:
df <- data.frame(A=1:10, B=2:11, C=3:12)
我试过申请:
cols<-c('A', 'B')
df[,cols]<-apply(df[,cols], 2, function(x){ as.factor(x)});
但是结果是一个字符class。
> class(df$A)
[1] "character"
如何在不对每一列执行 as.factor 的情况下执行此操作?
尝试
df[,cols] <- lapply(df[,cols],as.factor)
问题是 apply()
试图将结果绑定到矩阵中,这导致将列强制转换为字符:
class(apply(df[,cols], 2, as.factor)) ## matrix
class(as.factor(df[,1])) ## factor
相比之下,lapply()
对列表元素进行操作。
您可以将结果放回数据框中,该数据框将识别以下因素:
df[,cols]<-data.frame(apply(df[,cols], 2, function(x){ as.factor(x)}))
另一种选择,使用 purrr
和 dplyr
,可能比基本解决方案更具可读性,并将数据保存在数据框中:
这是数据:
df <- data.frame(A=1:10, B=2:11, C=3:12)
str(df)
'data.frame': 10 obs. of 3 variables:
$ A: int 1 2 3 4 5 6 7 8 9 10
$ B: int 2 3 4 5 6 7 8 9 10 11
$ C: int 3 4 5 6 7 8 9 10 11 12
我们可以轻松地对所有列进行操作 dmap
:
library(purrr)
library(dplyr)
# all cols to factor
dmap(df, as.factor)
Source: local data frame [10 x 3]
A B C
(fctr) (fctr) (fctr)
1 1 2 3
2 2 3 4
3 3 4 5
4 4 5 6
5 5 6 7
6 6 7 8
7 7 8 9
8 8 9 10
9 9 10 11
10 10 11 12
并且类似地在使用 dplyr
中的 select
的列子集上使用 dmap
:
# selected cols to factor
cols <- c('A', 'B')
df[,cols] <-
df %>%
select(one_of(cols)) %>%
dmap(as.factor)
获得想要的结果:
str(df)
'data.frame': 10 obs. of 3 variables:
$ A: Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10
$ B: Factor w/ 10 levels "2","3","4","5",..: 1 2 3 4 5 6 7 8 9 10
$ C: int 3 4 5 6 7 8 9 10 11 12
2017 年 11 月 9 日更新
purrr / purrrlyr 仍在开发中
与 Ben 的类似,但使用 purrrlyr::dmap_at
:
library(purrrlyr)
df <- data.frame(A=1:10, B=2:11, C=3:12)
# selected cols to factor
cols <- c('A', 'B')
(dmap_at(df, factor, .at = cols))
A B C
<fctr> <fctr> <int>
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
一个简单但有效的选择是 mapply
df <- data.frame(A=1:10, B=2:11, C=3:12)
cols <- c('A', 'B')
df[,cols] <- as.data.frame(mapply(as.factor,df[,cols]))
你也可以使用for循环来达到同样的效果:
for(col in cols){
df[,col] <- as.factor(df[,col])
}
这里有几个 tidyverse
选项 -
library(dplyr)
cols <- c('A', 'B')
df <- df %>% mutate(across(all_of(cols), factor))
str(df)
#'data.frame': 10 obs. of 3 variables:
# $ A: Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10
# $ B: Factor w/ 10 levels "2","3","4","5",..: 1 2 3 4 5 6 7 8 9 10
# $ C: int 3 4 5 6 7 8 9 10 11 12
使用map
-
df[cols] <- purrr::map(df[cols], factor)
我需要将许多数字列转换为因子类型。 一个例子 table:
df <- data.frame(A=1:10, B=2:11, C=3:12)
我试过申请:
cols<-c('A', 'B')
df[,cols]<-apply(df[,cols], 2, function(x){ as.factor(x)});
但是结果是一个字符class。
> class(df$A)
[1] "character"
如何在不对每一列执行 as.factor 的情况下执行此操作?
尝试
df[,cols] <- lapply(df[,cols],as.factor)
问题是 apply()
试图将结果绑定到矩阵中,这导致将列强制转换为字符:
class(apply(df[,cols], 2, as.factor)) ## matrix
class(as.factor(df[,1])) ## factor
相比之下,lapply()
对列表元素进行操作。
您可以将结果放回数据框中,该数据框将识别以下因素:
df[,cols]<-data.frame(apply(df[,cols], 2, function(x){ as.factor(x)}))
另一种选择,使用 purrr
和 dplyr
,可能比基本解决方案更具可读性,并将数据保存在数据框中:
这是数据:
df <- data.frame(A=1:10, B=2:11, C=3:12)
str(df)
'data.frame': 10 obs. of 3 variables:
$ A: int 1 2 3 4 5 6 7 8 9 10
$ B: int 2 3 4 5 6 7 8 9 10 11
$ C: int 3 4 5 6 7 8 9 10 11 12
我们可以轻松地对所有列进行操作 dmap
:
library(purrr)
library(dplyr)
# all cols to factor
dmap(df, as.factor)
Source: local data frame [10 x 3]
A B C
(fctr) (fctr) (fctr)
1 1 2 3
2 2 3 4
3 3 4 5
4 4 5 6
5 5 6 7
6 6 7 8
7 7 8 9
8 8 9 10
9 9 10 11
10 10 11 12
并且类似地在使用 dplyr
中的 select
的列子集上使用 dmap
:
# selected cols to factor
cols <- c('A', 'B')
df[,cols] <-
df %>%
select(one_of(cols)) %>%
dmap(as.factor)
获得想要的结果:
str(df)
'data.frame': 10 obs. of 3 variables:
$ A: Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10
$ B: Factor w/ 10 levels "2","3","4","5",..: 1 2 3 4 5 6 7 8 9 10
$ C: int 3 4 5 6 7 8 9 10 11 12
2017 年 11 月 9 日更新
purrr / purrrlyr 仍在开发中
与 Ben 的类似,但使用 purrrlyr::dmap_at
:
library(purrrlyr)
df <- data.frame(A=1:10, B=2:11, C=3:12)
# selected cols to factor
cols <- c('A', 'B')
(dmap_at(df, factor, .at = cols))
A B C
<fctr> <fctr> <int>
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
一个简单但有效的选择是 mapply
df <- data.frame(A=1:10, B=2:11, C=3:12)
cols <- c('A', 'B')
df[,cols] <- as.data.frame(mapply(as.factor,df[,cols]))
你也可以使用for循环来达到同样的效果:
for(col in cols){
df[,col] <- as.factor(df[,col])
}
这里有几个 tidyverse
选项 -
library(dplyr)
cols <- c('A', 'B')
df <- df %>% mutate(across(all_of(cols), factor))
str(df)
#'data.frame': 10 obs. of 3 variables:
# $ A: Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10
# $ B: Factor w/ 10 levels "2","3","4","5",..: 1 2 3 4 5 6 7 8 9 10
# $ C: int 3 4 5 6 7 8 9 10 11 12
使用map
-
df[cols] <- purrr::map(df[cols], factor)