如何在注意数字以前是否为负数的同时获得绝对值?
How to get the absolute value while noting if the number used to be negative?
我有一个遗传数据集,其中每一行都描述了一个基因,并且有一个包含多个 beta 值的 beta 列,我已将其压缩为一个 row/cell(从一个基因中的多个变体给出多个 beta 的变体级别). Beta 是基因在某种情况下可能产生的效应大小,因此大的负值和大的正值都很重要。我正在尝试编写从行中选择绝对值的代码,然后尝试创建另一个新列来记录绝对值是否曾经是负数 - 我有生物学背景所以我不确定这是否可能或最好的方法是什么?
例如我的数据是这样的:
Gene Beta
ACE 0.01, -0.6, 0.4
BRCA 0.7, -0.2, 0.2
ZAP70 NA
P53 0.8, -0.6, 0.001
预期输出如下(选择绝对值并跟踪哪些数字曾经是负数):
Gene Beta Negatives
ACE 0.6 1
BRCA 0.7 0
ZAP70 NA NA
P53 0.8 0
我目前坚持从每一行中获取绝对值,我正在尝试的是:
abs2 = function(x) if(all(is.na(x))) NA else abs(x,na.rm = T)
getabs = function(col) str_extract_all(col,"[0-9\.-]+") %>%
lapply(.,function(x)abs2(as.numeric(x)) ) %>%
unlist()
test <- df %>%
mutate_at(names(df)[2],getabs)
#Outputs:
Error in abs(x, na.rm = T) : 2 arguments passed to 'abs' which requires 1
任何关于如何获得每个 cell/row 的绝对值的帮助将不胜感激,因为我假设我也可以使列获得最大的负值,将其与相同的绝对值匹配并将其用作我的底片记录。
输入数据:
dput(df)
structure(list(Gene = c("ACE", "BRCA", "ZAP70", "P53"), `Beta` = c("0.01, -0.6, 0.4",
"0.7, -0.2, 0.2", "0.001, 0.02, -0.003", "0.8, -0.6, 0.001")), row.names = c(NA,
-4L), class = c("data.table", "data.frame"))
你可以简单地拆分,转换成数字,找到绝对最大值的索引并检查它是否为负数,即
sapply(strsplit(df$Beta, ', '), function(i){i1 <- as.numeric(i);
i2 <- which.max(abs(i1));
if (length(i2) == 0){NA}else{i[i2] < 0}}) * 1
#[1] 1 0 NA 0
使用 dplyr
的一种方法是将逗号分隔值放入单独的行中,group_by
Gene
获取 Beta
的 max
绝对值并检查该值是否为负数。
library(dplyr)
df %>%
tidyr::separate_rows(Beta, sep = ",", convert = TRUE) %>%
group_by(Gene) %>%
summarise(Negatives = +(min(Beta) == -max(abs(Beta))),
Beta = max(abs(Beta), na.rm = TRUE))
# A tibble: 4 x 3
# Gene Negatives Beta
# <fct> <int> <dbl>
#1 ACE 1 0.6
#2 BRCA 0 0.7
#3 P53 0 0.8
#4 ZAP70 NA -Inf
数据
df <- structure(list(Gene = structure(c(1L, 2L, 4L, 3L), .Label = c("ACE",
"BRCA", "P53", "ZAP70"), class = "factor"), Beta = structure(c(1L,
2L, NA, 3L), .Label = c("0.01, -0.6, 0.4", "0.7, -0.2, 0.2",
"0.8, -0.6, 0.001"), class = "factor")), class = "data.frame",
row.names = c(NA, -4L))
您可以编写自定义函数 f
并通过 Vectorize
对其进行矢量化,即
f <- Vectorize(function(x) {
v <- as.numeric(unlist(strsplit(as.character(x),split = ",")))
c(Beta = max(abs(v)),Negatives = sum(v<0 & v==-max(abs(v))))
})
然后 运行
df <- cbind(df[1],t(f(df$Beta)))
这样
> df
Gene Beta Negatives
1 ACE 0.6 1
2 BRCA 0.7 0
3 ZAP70 NA NA
4 P53 0.8 0
我有一个遗传数据集,其中每一行都描述了一个基因,并且有一个包含多个 beta 值的 beta 列,我已将其压缩为一个 row/cell(从一个基因中的多个变体给出多个 beta 的变体级别). Beta 是基因在某种情况下可能产生的效应大小,因此大的负值和大的正值都很重要。我正在尝试编写从行中选择绝对值的代码,然后尝试创建另一个新列来记录绝对值是否曾经是负数 - 我有生物学背景所以我不确定这是否可能或最好的方法是什么?
例如我的数据是这样的:
Gene Beta
ACE 0.01, -0.6, 0.4
BRCA 0.7, -0.2, 0.2
ZAP70 NA
P53 0.8, -0.6, 0.001
预期输出如下(选择绝对值并跟踪哪些数字曾经是负数):
Gene Beta Negatives
ACE 0.6 1
BRCA 0.7 0
ZAP70 NA NA
P53 0.8 0
我目前坚持从每一行中获取绝对值,我正在尝试的是:
abs2 = function(x) if(all(is.na(x))) NA else abs(x,na.rm = T)
getabs = function(col) str_extract_all(col,"[0-9\.-]+") %>%
lapply(.,function(x)abs2(as.numeric(x)) ) %>%
unlist()
test <- df %>%
mutate_at(names(df)[2],getabs)
#Outputs:
Error in abs(x, na.rm = T) : 2 arguments passed to 'abs' which requires 1
任何关于如何获得每个 cell/row 的绝对值的帮助将不胜感激,因为我假设我也可以使列获得最大的负值,将其与相同的绝对值匹配并将其用作我的底片记录。
输入数据:
dput(df)
structure(list(Gene = c("ACE", "BRCA", "ZAP70", "P53"), `Beta` = c("0.01, -0.6, 0.4",
"0.7, -0.2, 0.2", "0.001, 0.02, -0.003", "0.8, -0.6, 0.001")), row.names = c(NA,
-4L), class = c("data.table", "data.frame"))
你可以简单地拆分,转换成数字,找到绝对最大值的索引并检查它是否为负数,即
sapply(strsplit(df$Beta, ', '), function(i){i1 <- as.numeric(i);
i2 <- which.max(abs(i1));
if (length(i2) == 0){NA}else{i[i2] < 0}}) * 1
#[1] 1 0 NA 0
使用 dplyr
的一种方法是将逗号分隔值放入单独的行中,group_by
Gene
获取 Beta
的 max
绝对值并检查该值是否为负数。
library(dplyr)
df %>%
tidyr::separate_rows(Beta, sep = ",", convert = TRUE) %>%
group_by(Gene) %>%
summarise(Negatives = +(min(Beta) == -max(abs(Beta))),
Beta = max(abs(Beta), na.rm = TRUE))
# A tibble: 4 x 3
# Gene Negatives Beta
# <fct> <int> <dbl>
#1 ACE 1 0.6
#2 BRCA 0 0.7
#3 P53 0 0.8
#4 ZAP70 NA -Inf
数据
df <- structure(list(Gene = structure(c(1L, 2L, 4L, 3L), .Label = c("ACE",
"BRCA", "P53", "ZAP70"), class = "factor"), Beta = structure(c(1L,
2L, NA, 3L), .Label = c("0.01, -0.6, 0.4", "0.7, -0.2, 0.2",
"0.8, -0.6, 0.001"), class = "factor")), class = "data.frame",
row.names = c(NA, -4L))
您可以编写自定义函数 f
并通过 Vectorize
对其进行矢量化,即
f <- Vectorize(function(x) {
v <- as.numeric(unlist(strsplit(as.character(x),split = ",")))
c(Beta = max(abs(v)),Negatives = sum(v<0 & v==-max(abs(v))))
})
然后 运行
df <- cbind(df[1],t(f(df$Beta)))
这样
> df
Gene Beta Negatives
1 ACE 0.6 1
2 BRCA 0.7 0
3 ZAP70 NA NA
4 P53 0.8 0