这个问题有很多内容,我认为其中一些可能会让 R 初学者感到困惑,尤其是当您从不同类型的统计包或电子表格进入 R 时。还有一些乍一看会不一致,但最终会显得很自然。
这个问题的一部分是你的内存问题掩盖了另一个问题,这就是你如何做子集。解决子集问题很可能会解决内存问题。
R 中的数据框子集可以专注于行、列或两者。您可以根据布尔语句(可以评估为 TRUE 或 FALSE)选择整列或整行或行或列。在您的情况下,您想要选择具有特定名称的整个列。因此,您只想给出具体的名称。有两种方法可以得到相同的结果。
identical(iris[c("Sepal.Length","Petal.Length")],
iris[,c("Sepal.Length","Petal.Length")])
注意两者之间的细微差别。第一个简单地给出了向量中所需列的名称。这是利用数据框也是(列)列表的事实,您可以使用列表元素的名称对列表进行子集化,在本例中为列名。第二个利用了数据框的工作方式有点像矩阵的事实(可以有不同类型的数据,这使得它不是 R 中的矩阵)。像矩阵一样,您可以通过行和列来引用它的一部分,行、列用逗号分隔。这意味着如果您需要多行或多列,则需要将它们作为使用c() 创建的向量提供。
但重要的是要注意,您引用列的方式(使用$)表示法不是正确的方式。这实际上是引用整列数据作为向量(或者在 tidyverse 中作为一列的小标题)。换句话说,如果iris$Petal.Length 不只是说让我获得具有此名称的列,它实际上是说让我获得名称与鸢尾花 Petal.Length 列中的值匹配的所有列。
在您的原始代码中,这变得更加复杂,因为它说让我获得所有行名称在“品牌”列中具有值的行,这将导致各种问题,因为品牌可能不包含唯一值和行名应该是唯一的。
为了学习,我鼓励您使用 iris 之类的小数据集尝试所有这些变体(以及更多变体),这样您就可以在内存不足之前看到可能发生的大量错误消息。
加法:
只是为了添加更多内容......您可能已经使用了$ 表示法,因为您之前在子集的上下文中看到或使用过它,但这通常会在使用布尔语句的子集的上下文中。例如
iris[iris$Sepal.Length > 5,]
对那些 Sepal.Length 值大于 5 的 行 进行子集。它通过创建一个单独的逻辑向量来实现这一点,该向量具有与 iris 相同的行数,并且这些行的值为 TRUE Sepal.Length >5 的行,其他行为 false。然后仅保留与另一个向量中的 TRUE 行匹配的那些行。这是等价的。
x <- iris$Sepal.Length > 5
iris[x,]
要对列使用相同的逻辑语句概念,您需要一个与要保留的列名向量长度相同的逻辑向量。因此,例如 colnames() 给了我们列名的向量,然后
x
[1] TRUE FALSE FALSE FALSE TRUE
所以
iris[, colname(iris) %in% x]
会给我们一个数据框,其中只有两列声明为真。在您想要创建一个接受任意列名列表作为子集的函数之前,这似乎很复杂。