删除两列包含不同字母或缺失数据的行

Remove rows that contain different letters or missing data for two columns

我正在 R studio 中分析一个大数据集,我在编程方面不是很有经验。 我想删除包含 CONSENSUSMAP 和 SVEVOMAP 列的不同字母的行。此外,如果缺少列 "CONSENSUSMAP".

的数据

我写这个table作为例子:

CLONEID | CONSENSUSMAP| SVEVOMAP
1228104 |      NA     |    chr1A
2277691 |      NA     |    chr1A
2277607 |      1A     |    chr1A
1E+08   |      NA     |    chr1A
1229677 |      1B     |    chr1A
1126457 |      7B     |    chr7B

我想获得以下输出:

CLONEID | CONSENSUSMAP| SVEVOMAP
2277607 |       1A    |    chr1A
1126457 |       7B    |    chr7B

我尝试了一些代码,但其中 none 符合这些特定条件。有什么建议吗?

我们可以用 na.omit 换行,然后 distinct

library(dplyr)
df1 %>%
        filter(!is.na(CONSENSUSMAP)) %>%
        distinct(SVEVOMAP, .keep_all = TRUE)
#  CLONEID CONSENSUSMAP SVEVOMAP
#1 2277607           1A    chr1A
#2 1126457           7B    chr7B

或者如果是基于子串,那么

library(stringr)
df1 %>%
   filter(!is.na(CONSENSUSMAP), CONSENSUSMAP == str_sub(SVEVOMAP, 4, 5))
#   CLONEID CONSENSUSMAP SVEVOMAP
#1 2277607           1A    chr1A
#2 1126457           7B    chr7B

str_remove

df1 %>%
   filter(!is.na(CONSENSUSMAP), CONSENSUSMAP == str_remove(SVEVOMAP, 'chr'))

数据

df1 <- structure(list(CLONEID = c("1228104", "2277691", "2277607", "1e+08", 
"1229677", "1126457"), CONSENSUSMAP = c(NA, NA, "1A", NA, "1B", 
"7B"), SVEVOMAP = c("chr1A", "chr1A", "chr1A", "chr1A", "chr1A", 
"chr7B")), row.names = c(NA, -6L), class = "data.frame")

以下 dplyr 解决方案将完成问题的要求。

library(dplyr)

df1 %>%
  filter(!is.na(CONSENSUSMAP)) %>%
  mutate(newcol = sub("^[^[:digit:]]*(\d+.*$)", "\1", SVEVOMAP)) %>%
  filter(CONSENSUSMAP == newcol) %>%
  select(-newcol)
#  CLONEID CONSENSUSMAP SVEVOMAP
#1 2277607           1A    chr1A
#2 1126457           7B    chr7B

编辑。

这里有另外两种方式,都使用dplyr,第二种使用包stringr.

df1 %>%
  filter(!is.na(CONSENSUSMAP)) %>%
  rowwise() %>%
  filter(grepl(CONSENSUSMAP, SVEVOMAP))
#Source: local data frame [2 x 3]
#Groups: <by row>
#
## A tibble: 2 x 3
#  CLONEID CONSENSUSMAP SVEVOMAP
#  <chr>   <chr>        <chr>   
#1 2277607 1A           chr1A   
#2 1126457 7B           chr7B   


df1 %>%
  filter(!is.na(CONSENSUSMAP)) %>%
  filter(stringr::str_detect(SVEVOMAP, CONSENSUSMAP))
#  CLONEID CONSENSUSMAP SVEVOMAP
#1 2277607           1A    chr1A
#2 1126457           7B    chr7B

数据.

df1 <-
structure(list(CLONEID = c("1228104", "2277691", "2277607", "1e+08", 
"1229677", "1126457"), CONSENSUSMAP = c(NA, NA, "1A", NA, "1B", 
"7B"), SVEVOMAP = c("chr1A", "chr1A", "chr1A", "chr1A", "chr1A", 
"chr7B")), row.names = c(NA, -6L), class = "data.frame")

一种可能的base方式:

idx <- with(df, !is.na(CONSENSUSMAP) & mapply(grepl, CONSENSUSMAP, SVEVOMAP))

df[idx, ]

输出:

  CLONEID CONSENSUSMAP SVEVOMAP
3 2277607           1A    chr1A
6 1126457           7B    chr7B

请注意,这仅在 CONSENSUSMAP 中的整个模式与 SVEVOMAP 中的任何内容匹配时才会查找。

如果你真的只喜欢最后的字母,那么让我们稍微改变一下这个例子:

  CLONEID CONSENSUSMAP SVEVOMAP
1 1228104         <NA>    chr1A
2 2277691         <NA>    chr1A
3 2277607           1A    chr1A
4   1e+08         <NA>    chr1A
5 1229677           1B    chr1A
6 1126457           7B    chr6B

这里最后一条记录不会用上一种方法提取,而是用下一种方法提取:

idx <- with(df, !is.na(CONSENSUSMAP) & sub('\d+', '', CONSENSUSMAP) == sub('chr\d+(.*$)', '\1', SVEVOMAP))

df[idx, ]

  CLONEID CONSENSUSMAP SVEVOMAP
3 2277607           1A    chr1A
6 1126457           7B    chr6B