我有一个这样的数据框:
> dns1
variant_id gene_id pval_nominal
21821 chr1_165656237_T_C_b38 ENSG00000143149 1.24119e-05
21822 chr1_165659346_C_CA_b38 ENSG00000143149 1.24119e-05
21823 chr1_165659350_A_G_b38 ENSG00000143149 1.24119e-05
21824 chr1_165659415_A_G_b38 ENSG00000143149 1.24119e-05
21825 chr1_165660430_T_C_b38 ENSG00000143149 1.24119e-05
21826 chr1_165661135_T_G_b38 ENSG00000143149 1.24119e-05
21827 chr1_165661238_C_T_b38 ENSG00000143149 1.24119e-05
...
我想从第二列(variant_id)中删除所有字符,只提取第二个数字,看起来像这样:
165656237
165659346
165659350
165659415
165660430
165661135
165661238
...
我尝试过:
dns1$variant_id <- gsub('[^0-9.]','',dns1$variant_id)
但是使用上面的命令,我得到了:
> dns1
variant_id gene_id pval_nominal
21821 116565623738 ENSG00000143149 1.24119e-05
21822 116565934638 ENSG00000143149 1.24119e-05
21823 116565935038 ENSG00000143149 1.24119e-05
21824 116565941538 ENSG00000143149 1.24119e-05
...
所以这将匹配variant_id列中的所有数字,而我需要获取16565623738而不是116565623738。所以问题是如何在第二列中仅匹配第二个数字?
答案 0 :(得分:4)
您可以使用
dns1$variant_id <- sub('^[^_]*_(\\d+).*', '\\1', dns1$variant_id)
请参见regex demo
详细信息
^
-字符串的开头[^_]*
-除_
以外的0多个字符_
-下划线(\\d+)
-第1组:一个或多个数字.*
-字符串的其余部分。 sub
函数将仅对每个字符串执行一次搜索和替换操作,而替换中的\1
后向引用将把组1中的内容放回去。
variant_id <- c("chr1_165656237_T_C_b38", "chr1_165659346_C_CA_b38")
dns1 <- data.frame(variant_id)
dns1$variant_id <- sub('^[^_]*_(\\d+).*', '\\1', dns1$variant_id)
dns1
##=> variant_id
## 1 165656237
## 2 165659346
答案 1 :(得分:4)
我相信您可以按以下方式捕获数字:
gsub(".*?_([[:digit:]]+)_.*", "\\1", dns1$variant_id)
答案 2 :(得分:1)
这是一个超级hacky解决方案,它同时使用gsub和str_replace(来自stringr)。我确定有更好的解决方案,并且这要求variant_id始终以chr1_
开头,这可能不公平。
dns1$variant_id <- gsub('_(.*)','', str_replace(dns1$variant_id, 'chr1_',''))
答案 3 :(得分:1)
以下是使用stringr
的选项:
library(stringr)
df <-
data.frame(variant_id = c("chr1_165656237_T_C_b38",
"chr1_165659346_C_CA_b38",
"chr1_165659350_A_G_b38",
"chr1_165659415_A_G_b38",
"chr1_165660430_T_C_b38",
"chr1_165661135_T_G_b38",
"chr1_165661238_C_T_b38"))
df$variant_id_extract <-
str_replace(df$variant_id, "^.+_(\\d+)_.+$", "\\1")
df
#> variant_id variant_id_extract
#> 1 chr1_165656237_T_C_b38 165656237
#> 2 chr1_165659346_C_CA_b38 165659346
#> 3 chr1_165659350_A_G_b38 165659350
#> 4 chr1_165659415_A_G_b38 165659415
#> 5 chr1_165660430_T_C_b38 165660430
#> 6 chr1_165661135_T_G_b38 165661135
#> 7 chr1_165661238_C_T_b38 165661238
答案 4 :(得分:1)
您可以使用
dns$variant_id_new <- sapply(strsplit(as.character(dns$variant_id), "_"), unlist)[2,]
从逻辑上讲,这首先将variant_id
中的所有字符串除以_
。 sapply(,unlist)
将其转换为矩阵,在此我们取第二行(用于第二个变量)。