了解将因子强制转换为 R 数据帧中的字符
Understanding coercion of factors into characters in an R dataframe
试图弄清楚因子/数据框的强制转换在 R 中是如何工作的。我正在尝试为数据框的一个子集绘制箱线图。一步步来看
x = rnorm(30, 1, 1)
创建了一个具有正态分布的向量 x
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
创建了一个字符串,稍后用作绘制 x1、x2、x3 箱线图的一个因素
df = data.frame(x,c)
将 x 和 c 合并为 data.frame。所以现在我们期望 class
of df
: dataframe, df$x
: numeric, df$c
: factor(因为我们将 c 发送到数据帧中)和 is.data.frame
和is.list
应用于 df
应该给我们 TRUE
和 TRUE
。 (我假设所有数据帧也是列表?这就是为什么我们得到两个检查的 TRUE
。)
这就是下面发生的事情。到现在都还好。
class(df)
#[1] "data.frame"
is.data.frame(df)
#[1] TRUE
is.list(df)
#[1] TRUE
class(df$x)
#[1] "numeric"
class(df$c)
#[1] "factor"
现在我使用 c
中存在的因素对 x
的分布进行了分组。所以第一个参数是x ~ c
。但我只需要两个因素的箱线图:x1
和 x2
。所以我在 boxplot 函数中使用了一个 subset
参数。
boxplot(x ~ c, subset=c %in% c("x1", "x2"), data=df)
This is the plot we get, notice since x3 is a factor, it is still plotted
即尽管子集化为 2 个类别,我们在箱线图的 x 轴上仍然有 3 个类别。
所以,我找到的一个解决方案是将 df
变量的 class 更改为 numeric
和 character
class(df)<- c("numeric", "character")
boxplot(x ~ c, subset=c %in% c("x1", "x2"), data=df)
New boxplot. This is what we wanted, so it worked!, we plotted boxes for just x1 and x2, got rid of x3
但是如果我们只是 运行 相同的检查,我们 运行 在对所有变量进行强制转换之前,我们会得到这些输出。
有什么好玩的吗?
class(df)
#[1] "numeric" "character"
is.data.frame(df)
#[1] FALSE
is.list(df)
#[1] TRUE
class(df$x)
#[1] "numeric"
class(df$c)
#[1] "factor"
检查 df $ c(包含 caegories x1、x2、x3 的第二个变量)仍然是一个因子!
并且 df 不再是 list
(所以它曾经是一个列表吗?)
如果不更改 df $ c 的数据类型,我们通过 class(df)<- c("numeric", "character")
这种强制转换究竟做了什么?
综上所述,
我对 tldr 版本的问题:
R里都是dataframes
,还有lists
吗?
为什么我们的箱线图在第二种情况下下降了 x3(当我们将 class(df)
强制转换为 numeric
和 character
?
如果我们通过上述步骤强制转换为字符,为什么仍然显示变量的class是factor
?
为什么在我们完成上述步骤后 df
不再是 dataframe
?
如果我们以不同的顺序回答您的问题,答案会更有意义。
Are all dataframes, also lists in R?
是的。数据框是向量列表(列)。
And why did df stopped being a list after we did the above steps?
没有。它不再是数据框,因为您将 class 更改为 class(df)<- c("numeric", "character")
。 is.list(df)
returns 仍然正确。
If we did coerce factor into characters by doing the above steps, why is still showing that variable's class is factor?
class(df)
对 df
对象本身进行操作,而不是对列进行操作。看看str(df)
。因子列仍然是一个因子。 class(df)
将数据框对象本身的 class 属性设置为矢量。
Why did our boxplot dropped x3 in the 2nd case (when we coerced class(df) into numeric and character?
您通过将对象的 class 属性显式设置为向量 c("numeric", "character")
搞乱了数据框对象。很难预测其全部影响。我最好的猜测是箱线图或绘制轴的函数以某种方式访问了数据框的 class 属性。
做你真正想做的事:
x = rnorm(30, 1, 1)
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
df = data.frame(x,c)
df$c <- as.character(df$c)
或
x = rnorm(30, 1, 1)
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
df = data.frame(x,c, stringsAsFactors=FALSE)
像这样使用droplevels
:
df0 <- subset(df, c %in% c("x1", "x2"))
df0 <- transform(df0, c = droplevels(c))
levels(df0$c)
## [1] "x1" "x2"
请注意,现在 c
只有两个级别,而不是三个级别。
我们可以像这样使用 magrittr 将其写成管道:
library(magrittr)
df %>%
subset(c %in% c("x1", "x2")) %>%
transform(c = droplevels(c)) %>%
boxplot(x ~ c, data = .)
试图弄清楚因子/数据框的强制转换在 R 中是如何工作的。我正在尝试为数据框的一个子集绘制箱线图。一步步来看
x = rnorm(30, 1, 1)
创建了一个具有正态分布的向量 x
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
创建了一个字符串,稍后用作绘制 x1、x2、x3 箱线图的一个因素
df = data.frame(x,c)
将 x 和 c 合并为 data.frame。所以现在我们期望 class
of df
: dataframe, df$x
: numeric, df$c
: factor(因为我们将 c 发送到数据帧中)和 is.data.frame
和is.list
应用于 df
应该给我们 TRUE
和 TRUE
。 (我假设所有数据帧也是列表?这就是为什么我们得到两个检查的 TRUE
。)
这就是下面发生的事情。到现在都还好。
class(df)
#[1] "data.frame"
is.data.frame(df)
#[1] TRUE
is.list(df)
#[1] TRUE
class(df$x)
#[1] "numeric"
class(df$c)
#[1] "factor"
现在我使用 c
中存在的因素对 x
的分布进行了分组。所以第一个参数是x ~ c
。但我只需要两个因素的箱线图:x1
和 x2
。所以我在 boxplot 函数中使用了一个 subset
参数。
boxplot(x ~ c, subset=c %in% c("x1", "x2"), data=df)
This is the plot we get, notice since x3 is a factor, it is still plotted 即尽管子集化为 2 个类别,我们在箱线图的 x 轴上仍然有 3 个类别。
所以,我找到的一个解决方案是将 df
变量的 class 更改为 numeric
和 character
class(df)<- c("numeric", "character")
boxplot(x ~ c, subset=c %in% c("x1", "x2"), data=df)
New boxplot. This is what we wanted, so it worked!, we plotted boxes for just x1 and x2, got rid of x3
但是如果我们只是 运行 相同的检查,我们 运行 在对所有变量进行强制转换之前,我们会得到这些输出。
有什么好玩的吗?
class(df)
#[1] "numeric" "character"
is.data.frame(df)
#[1] FALSE
is.list(df)
#[1] TRUE
class(df$x)
#[1] "numeric"
class(df$c)
#[1] "factor"
检查 df $ c(包含 caegories x1、x2、x3 的第二个变量)仍然是一个因子!
并且 df 不再是 list
(所以它曾经是一个列表吗?)
如果不更改 df $ c 的数据类型,我们通过 class(df)<- c("numeric", "character")
这种强制转换究竟做了什么?
综上所述,
我对 tldr 版本的问题:
R里都是
dataframes
,还有lists
吗?为什么我们的箱线图在第二种情况下下降了 x3(当我们将
class(df)
强制转换为numeric
和character
?如果我们通过上述步骤强制转换为字符,为什么仍然显示变量的class是
factor
?为什么在我们完成上述步骤后
df
不再是dataframe
?
如果我们以不同的顺序回答您的问题,答案会更有意义。
Are all dataframes, also lists in R?
是的。数据框是向量列表(列)。
And why did df stopped being a list after we did the above steps?
没有。它不再是数据框,因为您将 class 更改为 class(df)<- c("numeric", "character")
。 is.list(df)
returns 仍然正确。
If we did coerce factor into characters by doing the above steps, why is still showing that variable's class is factor?
class(df)
对 df
对象本身进行操作,而不是对列进行操作。看看str(df)
。因子列仍然是一个因子。 class(df)
将数据框对象本身的 class 属性设置为矢量。
Why did our boxplot dropped x3 in the 2nd case (when we coerced class(df) into numeric and character?
您通过将对象的 class 属性显式设置为向量 c("numeric", "character")
搞乱了数据框对象。很难预测其全部影响。我最好的猜测是箱线图或绘制轴的函数以某种方式访问了数据框的 class 属性。
做你真正想做的事:
x = rnorm(30, 1, 1)
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
df = data.frame(x,c)
df$c <- as.character(df$c)
或
x = rnorm(30, 1, 1)
c = c(rep("x1",10), rep("x2",10), rep("x3",10))
df = data.frame(x,c, stringsAsFactors=FALSE)
像这样使用droplevels
:
df0 <- subset(df, c %in% c("x1", "x2"))
df0 <- transform(df0, c = droplevels(c))
levels(df0$c)
## [1] "x1" "x2"
请注意,现在 c
只有两个级别,而不是三个级别。
我们可以像这样使用 magrittr 将其写成管道:
library(magrittr)
df %>%
subset(c %in% c("x1", "x2")) %>%
transform(c = droplevels(c)) %>%
boxplot(x ~ c, data = .)