我想根据每个元素的最终编号分割以下数据帧。所以我想要6个新数据帧,每个数据帧包含两个元素。这是我尝试获取仅包含“ ABCD-1”和“ ABCC-1”的第一个子集的数据帧的方法,但似乎不起作用。
{{1}}
可以帮忙吗?
谢谢
阿比盖尔
答案 0 :(得分:3)
主要思想是创建一个用于定义拆分分组的因子。一种方法是使用正则表达式从提供的变量Barcode
中提取数字模式。然后,我们用as.factor()
将获得的数字字符向量转换为因子。
当然,我们可以使用其他正则表达式技术来完成工作,或者使用stringr
包中的更多用户友好的包装函数,就像第二个示例中一样(tidyverse
-ish方法)。 / p>
使用split
的基本R解决方案:
# 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]])
}
由reprex package(v0.3.0)于2020-02-24创建
而且,如果您愿意,这是一种tidyverse
式的方法:
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]])
由reprex package(v0.3.0)于2020-02-24创建
答案 1 :(得分:1)
您可以尝试
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
答案 2 :(得分:1)
这是另一个使用内置函数的解决方案:
dfs <- split(bar_f, gsub("\\D", "", DT$Barcode))
names(dfs) <- paste0("df_", names(dfs))
for(nm in names(dfs)) assign(nm, dfs[[nm]])