试图弄清楚因子/数据框的强制如何在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
df
:数据框,df$x
:数字,df$c
:因素(因为我们将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"
现在,我使用x
中存在的因子绘制c
的分布图。所以第一个参数是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 即,我们仍然在箱图的x轴上有3个类别,尽管可以分为两类。
因此,我找到的一个解决方案是将df
变量的类更改为numeric
和character
class(df)<- c("numeric", "character")
boxplot(x ~ c, subset=c %in% c("x1", "x2"), data=df)
但是如果我们只是运行相同的检查,我们在执行此强制操作之前运行,在所有变量上,我们得到这些输出。
有什么好玩的?
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 version 的问题:
R中是否所有dataframes
,lists
?
为什么我们的箱形图在第二种情况下丢失了x3(当我们将class(df)
强制转换为numeric
和character
时?
如果我们通过执行上述步骤将因素强制转换为字符,为什么仍然显示变量的类是factor
?
为什么df
在我们完成上述步骤后仍然不再是dataframe
?
答案 0 :(得分:0)
如果我们以不同的顺序提出问题,答案会更有意义。
是否所有数据框都列在R?
中
是。数据框是向量列表(列)。
为什么在我们完成上述步骤后df不再是一个列表?
它没有。它不再是数据框,因为您使用class(df)<- c("numeric", "character")
更改了类。 is.list(df)
仍然返回TRUE。
如果我们通过执行上述步骤将因素强制转换为字符,为什么仍然显示变量的类是因子?
class(df)
对df
对象本身进行操作,而不对列进行操作。看str(df)
。因子列仍然是一个因素。 class(df)
将数据框对象本身的class属性设置为向量。
为什么我们的boxplot在第二种情况下掉落了x3(当我们将类(df)强制转换为数字和字符时?
您通过将对象的class属性显式设置为向量c("numeric", "character")
来搞乱数据框对象。很难预测这种情况的全部影响。我最好的猜测是,boxplot或绘制轴的函数以某种方式访问数据框的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)
答案 1 :(得分:0)