Home > Mobile >  R subset data.frame by column names using partial string match from another list
R subset data.frame by column names using partial string match from another list

Time:10-21

I have a dataframe (called "myfile") like this:

      P3170.Tp2  P3189.Tn10 C453.Tn7 F678.Tc23 P3170.Tn10
gene1 0.3035130  0.5909081 0.8918271 0.2623648 0.13392672
gene2 0.2542919  0.5797730 0.4226669 0.9091961 0.96056308
gene3 0.9923911  0.4318736 0.7020107 0.1936181 0.58723105
gene4 0.4113318  0.1239206 0.4091794 0.8196982 0.54791214
gene5 0.4095719  0.6392045 0.4416208 0.8853356 0.01008299

I have a list of interesting strings (called "interesting.list") like this:

interesting.list <- c("P3170", "C453")

I would like to use this interesting.list and subset the myfile by partial string match of column headers.

ss.file <- NULL
for (i in 1:length(interesting.list)){
    ss.file[[i]] <- myfile[,colnames(myfile) %like% interesting.list[[i]]]
}

However, this loop doesnt provide the column headers after running. Since I have a huge dataset (more than 30000 rows), it would be hard to implement the colnames manually. is there a better way to do it?

CodePudding user response:

# Specify `interesting.list` items manually
df[,grep("P3170|C453", x=names(df))]
#>   P3170.Tp2 C453.Tn7 P3170.Tn10
#> 1         1        3          5

# Use paste to create pattern from lots of items in `interesting.list`
il <- c("P3170", "C453")
df[,grep(paste(il, collapse = "|"), x=names(df))]
#>   P3170.Tp2 C453.Tn7 P3170.Tn10
#> 1         1        3          5

Example data:

n <- c("P3170.Tp2" , "P3189.Tn10" ,"C453.Tn7" ,"F678.Tc23" ,"P3170.Tn10")
df <- data.frame(1,2,3,4,5)
names(df) <- n
Created on 2021-10-20 by the reprex package (v2.0.1)

CodePudding user response:

There are multiple things you need to think about on top of this question; what if an item in interesting.list returns more than one match, what if no matches are found, etc.

Here's one approach, given your data:

nms <- colnames(myFile)

matchIdx <- unlist(lapply(interesting.list, function(pattern) {
  matches <- which(grepl(pattern, nms, fixed = TRUE))

  # If more than one match is found, only return the first
  if (length(matches) > 1) matches[1] else matches
}))

myFile[, matchIdx, drop = FALSE]
  • Related