Разделение фрейма данных на основе символьной строки - PullRequest
1 голос
/ 24 февраля 2020

Я хотел бы разбить следующий фрейм данных на основе окончательных чисел каждого элемента. Поэтому я хотел бы 6 новых фреймов данных каждый с двумя элементами. Вот моя попытка получить фрейм данных первого подмножества, содержащего только «ABCD-1» и «AB CC -1», но, похоже, он не работает.

library("reshape2")
Barcode <- c("ABCD-1", "ABCC-1", "ABCD-2", "ABCC-2", "ABCD-3", "ABCC-3", 
"ABCD-4", "ABCC-4", "ABCD-5", "ABCC-5","ABCD-6", "ABCC-6")
bar_f <- data.frame(Barcode)
bar_f

bar_f$SampleID <- colsplit(bar_f$Barcode, pattern = "-", names = c("a","b"))$b
bar_f.s1 <- subset(barcode_file, barcode_file$SampleID == "1")
bar_f.s1

Вы можете помочь?

Спасибо,

Абигайль

Ответы [ 3 ]

3 голосов
/ 24 февраля 2020

Основная идея заключается в создании фактора, используемого для определения группировки для разбиения. Одним из способов является извлечение шаблона цифр из предоставленной переменной Barcode с использованием регулярного выражения. Затем мы конвертируем полученный символьный вектор цифр в коэффициент с as.factor(). Конечно, мы можем использовать другие методы регулярных выражений для выполнения работы или более удобные функции-оболочки из пакета stringr, как во втором примере (подход tidyverse -i sh).

Пример 1

Базовое решение R с использованием split:

# The provided data
Barcode <- c("ABCD-1", "ABCC-1", "ABCD-2", "ABCC-2", "ABCD-3", "ABCC-3", 
             "ABCD-4", "ABCC-4", "ABCD-5", "ABCC-5","ABCD-6", "ABCC-6")
bar_f <- data.frame(Barcode)

factor_for_split <- regmatches(x = bar_f$Barcode,
                               m = regexpr(pattern = "[[:digit:]]",
                                           text = bar_f$Barcode))
factor_for_split
#>  [1] "1" "1" "2" "2" "3" "3" "4" "4" "5" "5" "6" "6"

# Create a list of 6 data frames as asked
lst <- split(x = bar_f, f = as.factor(factor_for_split))
lst
#> $`1`
#>   Barcode
#> 1  ABCD-1
#> 2  ABCC-1
#> 
#> $`2`
#>   Barcode
#> 3  ABCD-2
#> 4  ABCC-2
#> 
#> $`3`
#>   Barcode
#> 5  ABCD-3
#> 6  ABCC-3
#> 
#> $`4`
#>   Barcode
#> 7  ABCD-4
#> 8  ABCC-4
#> 
#> $`5`
#>    Barcode
#> 9   ABCD-5
#> 10  ABCC-5
#> 
#> $`6`
#>    Barcode
#> 11  ABCD-6
#> 12  ABCC-6

# Edit names of the list
names(lst) <- paste0("df_", names(lst))

# Assign each data frame from the list to a data frame object in the global
# environment
for(name in names(lst)) {
  assign(name, lst[[name]])
}

Создано в 2020-02-24 с помощью пакета prepx (v0.3.0)

Пример 2

И, если хотите, подход tidyverse -i sh:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(stringr)

Barcode <- c("ABCD-1", "ABCC-1", "ABCD-2", "ABCC-2", "ABCD-3", "ABCC-3", 
             "ABCD-4", "ABCC-4", "ABCD-5", "ABCC-5","ABCD-6", "ABCC-6")
bar_f <- data.frame(Barcode)

bar_f %>% 
  mutate(factor_for_split = str_extract(string = Barcode,
                                        pattern = "[[:digit:]]")) %>% 
  group_split(factor_for_split)
#> [[1]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-1  1               
#> 2 ABCC-1  1               
#> 
#> [[2]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-2  2               
#> 2 ABCC-2  2               
#> 
#> [[3]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-3  3               
#> 2 ABCC-3  3               
#> 
#> [[4]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-4  4               
#> 2 ABCC-4  4               
#> 
#> [[5]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-5  5               
#> 2 ABCC-5  5               
#> 
#> [[6]]
#> # A tibble: 2 x 2
#>   Barcode factor_for_split
#>   <fct>   <chr>           
#> 1 ABCD-6  6               
#> 2 ABCC-6  6               
#> 
#> attr(,"ptype")
#> # A tibble: 0 x 2
#> # ... with 2 variables: Barcode <fct>, factor_for_split <chr>

names(lst) <- paste0("df_", 1:length(lst))
for(name in names(lst)) {
  assign(name, lst[[name]])

Создано в 2020-02-24 пакетом Представ (v0.3.0)

1 голос
/ 24 февраля 2020

Вот еще одно решение с использованием встроенных функций:

dfs <- split(bar_f, gsub("\\D", "", DT$Barcode))
names(dfs) <- paste0("df_", names(dfs))

for(nm in names(dfs)) assign(nm, dfs[[nm]])
1 голос
/ 24 февраля 2020

вы можете попробовать

library(tidyverse)
separate(bar_f, Barcode, into = letters[1:2], sep ="-")

и полный tidyvers путь может выглядеть как

bar_f %>% 
  separate(Barcode, into = letters[1:2], sep ="-") %>% 
  filter(b == 1)
     a b
1 ABCD 1
2 ABCC 1

в базе R вы можете попробовать gsub, который удаляет буквы И ПИСЬМА и -

bar_f$SampleID <- gsub("[aA-zZ|-]","",bar_f$Barcode)
head(bar_f)
  Barcode SampleID
1  ABCD-1        1
2  ABCC-1        1
3  ABCD-2        2
4  ABCC-2        2
5  ABCD-3        3
6  ABCC-3        3
...