【问题标题】:How to subset multiple columns from df including grep match如何从 df 中对多个列进行子集化,包括 grep 匹配
【发布时间】:2019-10-08 06:36:58
【问题描述】:

我有一个非常大的数据集,其中包含多个列,它们的名称有共同部分(例如 ctq_1、ctq_2、ctq_3 以及 panas_1、panas_2、panas_3)。我想将其中一些列(例如,仅列名中包含“panas”的列)与同一数据框中具有唯一名称(例如,id、组)的某些其他列一起子集。

我尝试在方括号内使用 grep 函数,效果很好: panas .data 中找不到列 114115116117118、……(以及更多 15 个)。 致电rlang::last_error() 以查看回溯。

如何用最简单的代码实现我想要的?我是 R 新手,所以最好避免使用花哨的功能!

这是一个可重现的例子。


> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

> newframe <- iris[ , grep('Petal', colnames(iris))] # This works

> newframe <- iris[ , c('Species', grep('Petal', colnames(iris)))] # This doesn't work

这一次,错误是:

[.data.frame(iris, , c("Species", grep("Petal", colnames(iris)))) 中的错误: 选择了未定义的列

【问题讨论】:

  • 尝试在您的grep 中使用|。像iris[grep("Spec.*|Peta.*", names(iris))] 这样的东西?也可以玩弄一些pasteing..

标签: r dataframe match subset partial


【解决方案1】:

假设我了解您想要做什么,可能的解决方案可能没有用和/或可能是多余的:

my_selector <- function(df,partial_name,...){
  positional_names <- match(...,names(df))
  df[,c(positional_names,grep(partial_name,names(df)))]
}
my_selector(iris, partial_name = "Petal","Species")

一个“更简单”的选项是使用grep 等来一次匹配目标名称:

iris[grep("Spec.*|Peta.*", names(iris))]

或者更简单,正如@akrun 建议的那样,我们可以简单地做:

iris[grep("(Spec|Peta).*", names(iris))]

对于更多列,我们可以这样做:

my_selector(iris, partial_name = "Petal",c("Species","Sepal.Length"))
       Species Sepal.Length Petal.Length Petal.Width
1       setosa          5.1          1.4         0.2
2       setosa          4.9          1.4         0.2

注意然而,在上述函数中,列的选择与直觉相反,因为最后提供的名称首先被选择。

第一部分的结果(截断):

         Species Petal.Length Petal.Width
1       setosa          1.4         0.2
2       setosa          1.4         0.2
3       setosa          1.3         0.2
4       setosa          1.5         0.2
5       setosa          1.4         0.2
6       setosa          1.7         0.4
7       setosa          1.4         0.3

【讨论】:

  • 也可以放在括号里grep("(Spec|Peta).*", names(iris))
【解决方案2】:

grep 返回匹配的位置,在子集列时不能混合列名和位置。完全按名称或按位置子集。

按名称做子集

panas <- bigdata[,c('id', 'group', grep('panas', colnames(bigdata), value = TRUE))] 

或按位置子集

panas <- bigdata[ , c(1:2, grep('panas', colnames(bigdata))]

假设1:2idgroup 列的列位置。

【讨论】:

  • 这非常清楚并且效果很好 - 非常感谢您的解决方案,特别是也非常清楚地解释了问题。
  • @Tory 欢迎您。顺便说一句,每个帖子只能选择一个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 2015-01-27
  • 1970-01-01
相关资源
最近更新 更多