一个可能的解决方案是使用stringr
and dplyr
:
library(dplyr)
library(stringr)
getmin = function(col) str_extract_all(col,"[0-9\\.-]+") %>%
lapply(.,function(x) min(as.numeric(x),na.rm = T) ) %>%
unlist()
df %>%
mutate_at(names(df)[-1],getmin)
Gene Pvalue1 Pvalue2 Pvalue3 Beta
1 Ace 0.00357 0.001385 0.00370 -3e-02
2 NOS Inf 0.020000 0.00067 9e-05
Warning messages:
1: In FUN(X[[i]], ...) : NAs introduced by coercion
2: In min(as.numeric(x), na.rm = T) :
no non-missing arguments to min; returning Inf
功能getmin
提取数字str_extract_all
:
str_extract_all(df$Pvalue2,"[0-9\\.-]+")
[[1]]
[1] "0.01755" "0.001385"
[[2]]
[1] "0.02"
它的优点是对空格或其他字符不敏感,但只能提取一个点。然后我循环这个列表以提取每个单元格中的最小值,并将列表转换为向量unlist
。使用as.numeric()
函数转换可能提取的.
to NA
.
代码df %>% mutate_at(names(df)[-1],getmin)
只需将此函数应用于除第一列之外的所有列
编辑:如果你想避免 inf 值,你可以使用这个稍微修改的版本:
min2 = function(x) if(all(is.na(x))) NA else min(x,na.rm = T)
getmin = function(col) str_extract_all(col,"[0-9\\.-]+") %>%
lapply(.,function(x)min2(as.numeric(x)) ) %>%
unlist()
df %>%
mutate_at(names(df)[-1],getmin)
Gene Pvalue1 Pvalue2 Pvalue3 Beta
1 Ace 0.00357 0.001385 0.00370 -3e-02
2 NOS NA 0.020000 0.00067 9e-05
data:
df <- read.table(text = "
Gene Pvalue1 Pvalue2 Pvalue3 Beta
Ace 0.0381,.,0.00357 0.01755,0.001385 0.0037,NA,0.039 -0.03,1,15
NOS NA 0.02 0.001,0.00067 0.00009,25,30
",header = T)