【问题标题】:Subset Columns based on partial matching of column names in the same data frame基于同一数据框中列名的部分匹配的子集列
【发布时间】:2016-10-23 12:46:41
【问题描述】:

我想了解如何通过将列名的前 5 个字母相互匹配来对同一数据框中的多个列进行子集化,如果它们相等,则对其进行子集化并将其存储在新变量中。

这是我所需输出的一个小解释。如下所述,

假设数据框是eatable

fruits_area   fruits_production  vegetable_area   vegetable_production 

12             100                26               324
33             250                40               580
66             510                43               581

eatable <- data.frame(c(12,33,660),c(100,250,510),c(26,40,43),c(324,580,581))
names(eatable) <- c("fruits_area", "fruits_production", "vegetables_area",
          "vegetable_production")

我正在尝试编写一个函数,该函数将匹配循环中的字符串,并在匹配列名中的前 5 个字母后存储子集列。

checkExpression <- function(dataset,str){
    dataset[grepl((str),names(dataset),ignore.case = TRUE)]
}

checkExpression(eatable,"your_string")

上述函数正确检查字符串,但我很困惑如何在数据集中的列名之间进行匹配。

编辑:- 我认为正则表达式可以在这里工作。

【问题讨论】:

  • 试试substr
  • 使用dplyr,相信你只想要select(eatable, starts_with("fruit"))
  • @aichao 我试过了。你的建议很好,但我想要的是自动检查数据框中的列名,如果它们匹配,子集。
  • 然后你可以像以前一样使用grepl,并将结果用于subset你的列subset(dataset,select=colnames(dataset)[cols]),其中colsgrepl的输出

标签: r regex if-statement string-parsing


【解决方案1】:

你可以试试:

v <- unique(substr(names(eatable), 0, 5))
lapply(v, function(x) eatable[grepl(x, names(eatable))])

或者使用map() + select_()

library(tidyverse)
map(v, ~select_(eatable, ~matches(.)))

这给出了:

#[[1]]
#  fruits_area fruits_production
#1          12               100
#2          33               250
#3         660               510
#
#[[2]]
#  vegetables_area vegetable_production
#1              26                  324
#2              40                  580
#3              43                  581

你是否想把它变成一个函数:

checkExpression <- function(df, l = 5) {
  v <- unique(substr(names(df), 0, l))
  lapply(v, function(x) df[grepl(x, names(df))])
}

然后简单地使用:

checkExpression(eatable, 5)

【讨论】:

  • 好主意!我以为substr 是矢量化的 :)
  • 确实如此。只需要一个功能就不需要 dplyr
  • @Sotos 是的。我想我会把它作为 base R 的替代品。如果它是更复杂管道的一部分,它可能会派上用场。
  • @StevenBeaupré 谢谢。现在从你的回答和 aichao 的回答中已经很清楚了。
【解决方案2】:

我相信这可能会满足您的需求:

checkExpression <- function(dataset,str){
  cols <- grepl(paste0("^",str),colnames(dataset),ignore.case = TRUE)
  subset(dataset,select=colnames(dataset)[cols])
}

注意在grepl 中使用的模式中添加了"^"

使用您的数据:

checkExpression(eatable,"fruit")
##  fruits_area fruits_production
##1          12               100
##2          33               250
##3         660               510
checkExpression(eatable,"veget")
##  vegetables_area vegetable_production
##1              26                  324
##2              40                  580
##3              43                  581

【讨论】:

  • 谢谢。有用。但史蒂文的回答更加自动化。
【解决方案3】:

您的函数完全符合您的要求,但出现了一个小错误:

checkExpression <- function(dataset,str){
  dataset[grepl((str),names(dataset),ignore.case = TRUE)]
}

将子集的对象名称从 obje 更改为 dataset

checkExpression(eatable,"fr")
#  fruits_area fruits_production
#1          12               100
#2          33               250
#3         660               510

checkExpression(eatable,"veg")
#  vegetables_area vegetable_production
#1              26                  324
#2              40                  580
#3              43                  581

【讨论】:

  • 实际上,我在本地 R 脚本中更正了它,并获得了与您类似的输出,但是在提问时输入错误。但是,我对其进行了编辑并更正了相同的问题。感谢您的关注。但是我的问题是在获得与您类似的输出之后开始的。 :)
  • 对不起,我误解了这个问题。
猜你喜欢
  • 1970-01-01
  • 2022-11-22
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2020-11-21
  • 2017-01-21
相关资源
最近更新 更多