从整数向量手动构造因子
Manually construct factor from integer vector
我想了解 R 中的各种对象是如何由原子向量和通用向量组成的。
可以通过手动设置属性 names
、row.names
和 class
从 list
构造 data.frame
,请参阅 here.
我想知道这对因子有何作用,因子在内部表示为整数向量。我想出的解决方案如下:
> f <- 1:3
> class(f) <- "factor"
> levels(f) <- c("low", "medium", "high")
Warning message:
In str.default(val) : 'object' does not have valid levels()
但出于某种原因,这看起来仍然与正确构造的因子不同:
> str(unclass(f))
int [1:3] 1 2 3
- attr(*, "levels")= chr [1:3] "low" "medium" "high"
> str(unclass(factor(c("low", "medium", "high"))))
int [1:3] 2 3 1
- attr(*, "levels")= chr [1:3] "high" "low" "medium"
我错过了什么吗? (我知道这可能不应该在生产代码中使用,而是仅用于教育目的。)
顺序很重要。
f <- 1:3
levels(f) <- c("low", "medium", "high") ## mark
class(f) <- "factor"
f
# [ 1] low medium high
# Levels: low medium high
`levels<-`
向向量添加一个属性,而不是行 ## mark 你也可以这样做
attr(f, 'levels') <- c("low", "medium", "high")
这里一步一步发生了什么:
f <- 1:3
attributes(f)
# NULL
levels(f) <- c("low", "medium", "high")
attributes(f)
# $levels
# [1] "low" "medium" "high"
class(f) <- "factor"
attributes(f)
# $levels
# [1] "low" "medium" "high"
#
# $class
# [1] "factor"
检查“自动”因子生成。
attributes(factor(1:3, labels=c("low", "medium", "high")))
# $levels
# [1] "low" "medium" "high"
#
# $class
# [1] "factor"
而且,重要的是
stopifnot(all.equal(unclass(f),
unclass(factor(1:3, labels=c("low", "medium", "high")))))
注 1, f
的顺序无关紧要。 f
的级别由它们的索引标识,分配的级别向量的元素 n 成为第一级别,即以下示例中的 `1`='low', `2`='medium', `3`='high'
。
f <- 3:1
levels(f) <- c("low", "medium", "high")
class(f) <- 'factor'
f
# [1] high medium low
# Levels: low medium high
注意 2, 这仅在 f
以 1
开头并且级别增加 1
时有效,因为一个因素实际上是一个带标签的整数结构。
g <- 2:4
levels(g) <- c("low", "medium", "high")
class(g) <- 'factor'
g
# Error in as.character.factor(x) : malformed factor
h <- c(1, 3, 4)
levels(h) <- c("low", "medium", "high")
class(h) <- 'factor'
# Error in class(h) <- "factor" :
# adding class "factor" to an invalid object
我想了解 R 中的各种对象是如何由原子向量和通用向量组成的。
可以通过手动设置属性 names
、row.names
和 class
从 list
构造 data.frame
,请参阅 here.
我想知道这对因子有何作用,因子在内部表示为整数向量。我想出的解决方案如下:
> f <- 1:3
> class(f) <- "factor"
> levels(f) <- c("low", "medium", "high")
Warning message:
In str.default(val) : 'object' does not have valid levels()
但出于某种原因,这看起来仍然与正确构造的因子不同:
> str(unclass(f))
int [1:3] 1 2 3
- attr(*, "levels")= chr [1:3] "low" "medium" "high"
> str(unclass(factor(c("low", "medium", "high"))))
int [1:3] 2 3 1
- attr(*, "levels")= chr [1:3] "high" "low" "medium"
我错过了什么吗? (我知道这可能不应该在生产代码中使用,而是仅用于教育目的。)
顺序很重要。
f <- 1:3
levels(f) <- c("low", "medium", "high") ## mark
class(f) <- "factor"
f
# [ 1] low medium high
# Levels: low medium high
`levels<-`
向向量添加一个属性,而不是行 ## mark 你也可以这样做
attr(f, 'levels') <- c("low", "medium", "high")
这里一步一步发生了什么:
f <- 1:3
attributes(f)
# NULL
levels(f) <- c("low", "medium", "high")
attributes(f)
# $levels
# [1] "low" "medium" "high"
class(f) <- "factor"
attributes(f)
# $levels
# [1] "low" "medium" "high"
#
# $class
# [1] "factor"
检查“自动”因子生成。
attributes(factor(1:3, labels=c("low", "medium", "high")))
# $levels
# [1] "low" "medium" "high"
#
# $class
# [1] "factor"
而且,重要的是
stopifnot(all.equal(unclass(f),
unclass(factor(1:3, labels=c("low", "medium", "high")))))
注 1, f
的顺序无关紧要。 f
的级别由它们的索引标识,分配的级别向量的元素 n 成为第一级别,即以下示例中的 `1`='low', `2`='medium', `3`='high'
。
f <- 3:1
levels(f) <- c("low", "medium", "high")
class(f) <- 'factor'
f
# [1] high medium low
# Levels: low medium high
注意 2, 这仅在 f
以 1
开头并且级别增加 1
时有效,因为一个因素实际上是一个带标签的整数结构。
g <- 2:4
levels(g) <- c("low", "medium", "high")
class(g) <- 'factor'
g
# Error in as.character.factor(x) : malformed factor
h <- c(1, 3, 4)
levels(h) <- c("low", "medium", "high")
class(h) <- 'factor'
# Error in class(h) <- "factor" :
# adding class "factor" to an invalid object