R 函数,用于将数据帧中的行与另一个数据帧中的模式进行匹配并添加分组变量

问题描述 投票:0回答:1

我正在尝试创建一个函数,对于给定数据帧中的每一行,将具有 %like% 的模式与该行中列的内容进行匹配,然后将特定类别名称粘贴到该列中。目的是拥有一个函数,我可以使用它来将基因列表及其描述与分组中编码的蛋白质类型进行匹配。

此函数应该针对 DATA 中的每一行,针对 LIST 中的每一行进行扫描,如果 LIST$column 中命名的 DATA 中的列与该行的 LIST$ 模式匹配,则应粘贴 LIST$name 中的名称进入 DATA$Function。

所以将此作为列表:

testdf <- data.frame(pattern = c("vers", "set", "abc"),
                     name = c("Versicolor Iris", "Setosa Iris", "Alphabet Iris"),
                     column = "Species")

在 iris 上运行代码作为数据应该返回前几行:

 Sepal.Length Sepal.Width Petal.Length Petal.Width Species Function
1          5.1         3.5          1.4         0.2  setosa  Setosa Iris
2          4.9         3.0          1.4         0.2  setosa  Setosa Iris
3          4.7         3.2          1.3         0.2  setosa  Setosa Iris
4          4.6         3.1          1.5         0.2  setosa  Setosa Iris

我原来手动执行此操作的笨重代码如下:

group_1 <- iris|> filter(Species %like% "set")
group1$Function <- "Setosa Iris"

然后在最后使用 rbind 重新组合所有组。

我希望能够创建一个包含所有潜在分组信息(要匹配的列、要匹配的模式、要粘贴的分组变量的名称)的 csv 文件,并运行我的函数将我的数据与该文件逐行进行比较,以创建分组变量。

不幸的是,列表中的列名称部分至关重要,因为我希望按顺序扫描行,有些可能通过基因 ID 来分离单个基因,而不是根据描述来分离该类型的所有基因,并且基因 ID 和描述是在不同的列中。

目前这是我的函数,但它不起作用并且使用了 for 循环,这可能最终成为瓶颈:

require(data.table)

testdf <- data.frame(pattern = c("vers", "set", "abc"),
                     name = c("Versicolor Iris", "Setosa Iris", "Alphabet Iris"),
                     column = "Species", "Species", "Petal.Width")

Function2 <- function(data, list, groupingcategoryname="Function"){
  
  groups <- data
  
  groups$Function <- "1"
  
  group_by_desc <- function(x){
    for (i in {{list}}$column) {if(groups[[i]] %like% {{list}}$pattern) {
      groups$Function <- {{list}}$name
    }else {groups$Function <- "no match"}
  }
  }
  data <- apply(X=data, 1, FUN=group_by_desc)
  
}

test <- Function2(data=iris, list=testdf)
r for-loop data.table apply sql-like
1个回答
0
投票

我认为

for
循环是一个很好的方法。
data.table::"%like%"()
运算符只是
grepl
的包装,因此我将消除对
data.table
的依赖并直接使用
grepl
。然后我们就可以直接替换了,在函数内部定义一个函数似乎没有必要。

Function2 <- function(data, list, groupingcategoryname="Function"){
  ## create column with default value
  data[[groupingcategoryname]] = "no match"

  ## loop through `list` data frame making replacements
  for(i in 1:nrow(list)) {
    data[
      ## rows
      grepl(pattern = list$pattern[i], x = data[[list$column[i]]]), 
      ## column
      groupingcategoryname
    ] = list$name[i] ## new value
  }
  data
}
Function2(iris, testdf)
#     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species        Function
# 1            5.1         3.5          1.4         0.2     setosa     Setosa Iris
# 2            4.9         3.0          1.4         0.2     setosa     Setosa Iris
# 3            4.7         3.2          1.3         0.2     setosa     Setosa Iris
# 4            4.6         3.1          1.5         0.2     setosa     Setosa Iris
# ...
© www.soinside.com 2019 - 2024. All rights reserved.