我有一个数据框,其中每个样本的列可以有多个值,例如:
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
我想对每列中的每个基因数据(我总共有数千个基因)应用 min()
和 max()
并获取最小值p 值,但 beta 等列的最大值。因此输出数据将如下所示:
Gene Pvalue1 Pvalue2 Pvalue3 Beta
Ace 0.00357 0.001385 0.0037 15
NOS NA 0.02 0.00067 30
我是 R 新手,不确定我所问的是否可能,如果一个单元格中有多个值,它们是否被视为字符串?
最佳答案
使用stringr
和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()
函数将可能提取的 .
转换为 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
数据:
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)
关于r - 选择一个单元格内的最小值或最大值(分隔字符串),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59786200/