通过部分列字符识别R删除数据框中的列

Remove columns in a dataframe by partial columns characters recognition R

我想通过选择具有部分字符识别功能的列来对我的数据框进行子集化,这在我只有一个 "name" 需要识别时有效。 数据框是:

         ABBA01A ABBA01B ABBA02A ABBA02B ACRU01A ACRU01B ACRU02A ACRU02B 
    1908      NA      NA      NA      NA      NA      NA      NA      NA           
    1909      NA      NA      NA      NA      NA      NA      NA      NA          
    1910      NA      NA      NA      NA      NA      NA      NA      NA         
    1911      NA      NA      NA      NA      NA      NA      NA      NA      
    1912      NA      NA      NA      NA      NA      NA      NA      NA      
    1913      NA      NA      NA      NA      NA      NA      NA      NA      

    library(stringr)
    df[str_detect(names(df), "ABBA" )]

有效,并且 returns:

         ABBA01A ABBA01B ABBA02A ABBA02B 
    1908      NA      NA      NA      NA    

所以,我想为我的每个物种创建一个数据框:

    Speciesnames=unique ( substring (names(df),0, 4))
    Speciesnames
     [1] "ABBA" "ACRU" "ARCU" "PIAB" "PIGL" 

我尝试制作一个循环并使用 [i] 作为物种名称,但 str_detect 函数无法识别它。 我想在循环中添加额外的计算

    for ( i in seq_along(Speciesnames)){

      df=df[str_detect(names(df), pattern =[i])]

      print(df)
     #my function for the subsetted dataframe
    }

感谢您的帮助!

我认为您应该先 select 所有匹配的列,然后 select 您的 data.frame。

patterns <- c("ABB", "CDC")
res <- lapply(patterns, function(x) grep(x, colnames(df), value=TRUE))
df[, unique(unlist(res))]

res 对象是每个模式的匹配列的列表

下一步是 select 唯一的一组列:unique(unlist(res)) 和 subselect data.frame.

如果您正在编写 production 代码,那可能不是最佳答案。

使用您的数据,您可以执行以下操作:

  1. 创建一个列表来保存要创建的 data.frames。
  2. 筛选 data.frames 并存储在列表中
  3. 给每个 data.frame 物种的名称
  4. 将全局环境全部data.frames带出列表

    Speciesnames <- unique(substring(names(df),0, 4))
    
    data <- vector("list", length(Speciesnames))
    
    for(i in seq_along(Speciesnames)) {
      data[[i]] <- df %>% select(starts_with(Speciesnames[i]))
    }
    names(data) <- Speciesnames
    
    list2env(data, envir = globalenv())
    

list2env 之后的最终结果是 2 data.frames 调用 "ABBA" "ACRU" 然后您可以访问。如果需要进一步操作,您可以将所有内容留在列表中并在那里进行。

一个选项是使用 mapplySIMPLIFY=FALSE 到 return 每个物种的数据框列表。 base-R 中的 startsWith 函数将为以物种名称开头的子集列提供选项。

# First find species but taking unique first 4 characters from column names
species <- unique(gsub("([A-Z]{4}).*", "\1",names(df)))

# Pass each species 
listOfDFs <- mapply(function(x){
  df[,startsWith(names(df),x)]    # Return only columns starting with species
}, species, SIMPLIFY=FALSE)

listOfDFs
# $ABBA
#      ABBA01A ABBA01B ABBA02A ABBA02B
# 1908      NA      NA      NA      NA
# 1909      NA      NA      NA      NA
# 1910      NA      NA      NA      NA
# 1911      NA      NA      NA      NA
# 1912      NA      NA      NA      NA
# 1913      NA      NA      NA      NA
# 
# $ACRU
#      ACRU01A ACRU01B ACRU02A ACRU02B
# 1908      NA      NA      NA      NA
# 1909      NA      NA      NA      NA
# 1910      NA      NA      NA      NA
# 1911      NA      NA      NA      NA
# 1912      NA      NA      NA      NA
# 1913      NA      NA      NA      NA

数据:

df <- read.table(text =  
"ABBA01A ABBA01B ABBA02A ABBA02B ACRU01A ACRU01B ACRU02A ACRU02B 
1908      NA      NA      NA      NA      NA      NA      NA      NA           
1909      NA      NA      NA      NA      NA      NA      NA      NA          
1910      NA      NA      NA      NA      NA      NA      NA      NA         
1911      NA      NA      NA      NA      NA      NA      NA      NA      
1912      NA      NA      NA      NA      NA      NA      NA      NA      
1913      NA      NA      NA      NA      NA      NA      NA      NA",
header = TRUE, stringsAsFactors = FALSE)