R - 具有特定映射的数值变化因子

时间:2014-02-27 00:42:17

标签: r dataframe

假设我在数据框中读取,其中列包含字符串作为因子。我想将这些因素转换为数字,但使用特定映射。这种转换通常是后续计算的前兆步骤。例如:

> library(rpart)

> head(car90["Type"])
                 Type
Acura Integra   Small
Acura Legend   Medium
Audi 100       Medium
Audi 80       Compact
BMW 325i      Compact
BMW 535i       Medium

> summary(car90$Type)
Compact   Large  Medium   Small  Sporty     Van    NA's 
     19       7      26      22      21      10       6

在car90 $ Type列中,我想将'Compact'设置为-10,'Large'设置为-1,'Medium'设置为0,'Small'设置为1,'Sporty'设置为10,'Van'是20,其中数字是数字,而不是因素。我该怎么做?

我已经查看了相关问题,但没有提供解决方案。

Replace specific column "words" into number or blank

Changing column names of a data frame in R

Replace contents of factor column in R dataframe

Convert factor to integer

6 个答案:

答案 0 :(得分:1)

我只想使用矢量下标;这是一个例子:

R>a <- as.factor(c("C", "L", "M", "L", "C"))
R>a
[1] C L M L C
Levels: C L M
R>b <- c(C=-10,L=-1,M=0)
R>b
  C   L   M 
-10  -1   0 
R>
R>b[a]
  C   L   M   L   C 
-10  -1   0  -1 -10 
R>

答案 1 :(得分:1)

你可以试试这个

x <- c('Compact', 'Large', 'Medium', 'Small', 'Sporty', 'Van') 
y <-  factor(x, levels = c('Compact', 'Large', 'Medium', 'Small', 'Sporty', 'Van'), 
    labels = c(-10, -1, 0, 1, 10, 20))
as.numeric(as.character(y))


[1] -10  -1   0   1  10  20

根据您的情况,您可以致电:

car90$Type <-  factor(car90$Type, levels = c('Compact', 'Large', 'Medium', 'Small', 'Sporty', 'Van'), 
    labels = c(-10, -1, 0, 1, 10, 20))
car90$Type <-  as.numeric(as.character(car90$Type))

答案 2 :(得分:1)

正如@NealFultz所说,矢量下标可以实现这一点。尽管如此,你必须小心谨慎地执行此操作:

x <- car90$Type[1:10]
#[1] Small   Medium  Medium  Compact Compact Medium  Medium  Large   Large   <NA>
#Levels: Compact Large Medium Small Sporty Van

I.e。:

vals <- c(Compact=-10,Large=-1,Medium=0,Small=1,Sporty=10,Van=20)
vals[x]

由于vals中的订单与因子levels中的x相同,因此会给出正确的结果:

vals[x]
#  Small  Medium  Medium Compact Compact  Medium  Medium   Large   Large    <NA> 
#      1       0       0     -10     -10       0       0      -1      -1      NA 

如果您更改vals中的顺序,例如:

,则会失效
vals <- c(Large=-1,Compact=-10,Medium=0,Small=1,Sporty=10,Van=20)
vals[x]
#  Small  Medium  Medium   Large   Large  Medium  Medium Compact Compact    <NA> 
#      1       0       0      -1      -1       0       0     -10     -10      NA 

您可以通过基于将x中的字符表示与names vals中的字符表示进行比较而不是顺序来解决此问题,例如:

vals <- c(Large=-1,Compact=-10,Medium=0,Small=1,Sporty=10,Van=20)
vals[as.character(x)]
#  Small  Medium  Medium Compact Compact  Medium  Medium   Large   Large    <NA> 
#      1       0       0     -10     -10       0       0      -1      -1      NA 

答案 3 :(得分:0)

这是一个连接操作

encode <- data.frame(Type = c("Compact", "Large", "Medium", "Small", "Sporty", "Van"), TypeValue = c(-10,-1,0,1,10,20))

car90 <- merge(car90, encode, all.x = TRUE)

# or using dplyr
library(dplyr)
car90 <- left_join(car90, encode)

答案 4 :(得分:0)

使用merge(),如下例所示。

首先使用您想要的值创建数据框。在这种情况下,你会写

 dictionary <- data.frame(Type = c('Compact', 'Large', 'Medium', 'Small', 'Sporty', 'Van'),
                     Values = c(-10, -1, 0, 1, 10, 20))

 output <- merge(car90$Type, dictionary)

重要提示:此示例不考虑NA。如果你想给它们一个值,你需要将它包含在具有自己值的类型中。否则这些行将不是输出的一部分。

生成的数据框按您希望的格式化。

注意:如果列的名称完全相同,则更容易,但您可以定义要与x一起使用的列,并查看文档以获取更多信息。

答案 5 :(得分:0)

只需重置级别:

levels(car90$Type) <- c(-10, -1, 0, 1, 10, 20)

导致(与您相同的头部/子集):

#               Type
# Acura Integra    1
# Acura Legend     0
# Audi 100         0
# Audi 80        -10
# BMW 325i       -10
# BMW 535i         0

虽然要小心,但如果您打算对此进行计算,则必须as.numeric(levels(fac))[fac]确保计算数字,而不是基础因素整数值。