使用colnames作为变量构造函数

时间:2015-12-14 08:13:27

标签: r function apply

我想在annot data.frame的多个列下收集字词。 以下是annot的玩具数据集的第一行信息。

colnames(annot)
# [1] "HUGO.Name"   "Common.Name" "Gene.Class"  "Cell.Type"   "Annotation" 
annot[1,]
#   HUGO.Name Common.Name                           Gene.Class Cell.Type
# 1      CCL1        CCL1 Immune Response - Cell Type specific       aDC
#                                                            Annotation
# 1 Cell Type specific, Chemokines and receptors, Inflammatory response

到目前为止,我一直在迭代地编写colnames,但我想学习如何编写一个函数来遍历annot的所有列(更常见的是其他{{1} }})。

这是我的手动方法:

data.frames

我如何构建一个函数" y"简化这个过程?我尝试过以下方法:

yA <- unique(str_trim(unlist(strsplit(annot[, "Annotation"], ","))))
yC <- unique(str_trim(unlist(strsplit(annot[, "Cell.Type"], ","))))

yA
#  [1] "Cell Type specific"                  "Chemokines and receptors"           
#  [3] "Inflammatory response"               "Cytokines and receptors"            
#  [5] "Chronic inflammatory response"       "Th2 orientation"                    
#  [7] "T-cell proliferation"                "Defense response to virus"          
#  [9] "B-cell receptor signaling pathway"   "CD molecules"                       
# [11] "Regulation of immune response"       "Adaptive immune response"           
# [13] "Antigen processing and presentation"

但是,当我尝试使用此功能时出现错误。

y <- function (i,n) {unique(str_trim(unlist(strsplit(i[, as.name(n)], ","))))}

我打算使用yA和yC的输出来制作如下列表:

yA <- y(annot, Annotation)
# Error in .subset(x, j) : invalid subscript type 'symbol'
# Called from: `[.data.frame`(i, , as.name(n))

1 个答案:

答案 0 :(得分:2)

我们假设您从data.frame开始:

mydf <- data.frame(
  v1 = c("A, B, B", "A, C,D"), 
  v2 = c("E, F", " G,H , E, I"), 
  v3 = c("J,K,L,M", "N, J, L, M, K"))

mydf
#        v1          v2            v3
# 1 A, B, B        E, F       J,K,L,M
# 2  A, C,D  G,H , E, I N, J, L, M, K

您可以定义功能的一种方法如下。我坚持使用基本功能,但如果您愿意,可以使用“stringr”。

myFun <- function(instring) {
  if (!is.character(instring)) instring <- as.character(instring)
  unique(trimws(unlist(strsplit(instring, ",", fixed = TRUE))))
}

第一行只是检查输入是否是字符串。通常,在data.frame s中,默认情况下会使用stringsAsFactors = TRUE读取数据,因此您需要先执行该转换。第二行进行分割和修剪。为了提高效率,我在其中添加了fixed = TRUE

一旦有了这样的功能,您就可以使用apply(按data.framematrix,按行或按列)或使用{{1}轻松应用此功能(对于lapplylist(按列排列))。

data.frame

另一方面,如果您要创建一个接受输入数据集名称和(裸,未引用)列的函数,您可以编写如下函数:

## If `mydf` is a data.frame, and you want to go by columns
lapply(mydf, myFun) 
# $v1
# [1] "A" "B" "C" "D"
# 
# $v2
# [1] "E" "F" "G" "H" "I"
# 
# $v3
# [1] "J" "K" "L" "M" "N"

## `apply` can be used too. Second argument specifies whether by row or column
apply(mydf, 1, myFun)
apply(mydf, 2, myFun)

第一行将裸列名称捕获为字符串,以便可以以典型的myOtherFun <- function(indf, col) { col <- deparse(substitute(col)) unique(trimws(unlist(strsplit(as.character(indf[, col]), ",", TRUE)))) } 形式使用。

这是使用中的功能:

my_data[, "col_wanted"]