基于同一数据框中列名的部分匹配的子集列
Subset Columns based on partial matching of column names in the same data frame
我想了解如何通过将列名称的前 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")
上面的函数正确地检查了字符串,但我对如何在数据集中的列名之间进行匹配感到困惑。
编辑:- 我认为这里可以使用正则表达式。
你可以试试:
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)
我相信这可以满足您的需求:
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
你的函数完全符合你的要求,但有一个小错误:
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
我想了解如何通过将列名称的前 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")
上面的函数正确地检查了字符串,但我对如何在数据集中的列名之间进行匹配感到困惑。
编辑:- 我认为这里可以使用正则表达式。
你可以试试:
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)
我相信这可以满足您的需求:
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
你的函数完全符合你的要求,但有一个小错误:
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