如何在 R 中获取具有负值的 Boxplot 矩阵的 Log2
How to take Log2 of a matrix having negative values for Boxplot in R
我有一个包含三列的矩阵,值有很多变化,从大的正值到 0 再到大的负值。为了更好地表示数据,我想取所有值的 log2,但由于不可能取负值和 0 的 log2,我想执行以下操作:
- 如果 number = 0 则将其更改为 1 并取 log2
- 如果数字 < 0 则取绝对值的 log2 并将负数赋给它
- 如果数字 > 0 则取数字的 log2
我正在尝试使用以下代码执行此操作,但到目前为止没有成功:
Log2Transformed <- ifelse(df == 0, 1, log2(df) & ifelse(df < 0, -log2(abs(df)), log2(df)))
head(df)
Open_TD Close_TD Invariant_TD
[1,] 1 6 5
[2,] 2 2 4
[3,] 0 0 -1
[4,] 0 0 2
[5,] NA 0 2
[6,] NA 0 1
可能有一些聪明的方法可以做到这一点,但我会花时间更清楚地定义每个步骤。
## Create dummy data
dd = data.frame(x = c(0, rnorm(100)))
首先为转换后的数据创建一列
dd$trans = dd$x
然后按照您的规则逐渐操作该列
#If number = 0 then change it to 1 and take log2
dd$trans[dd$x==0] = log2(1)
#If number < 0 then take log2 of absolute value
# and assign the negative number to it
dd$trans[dd$x< 0] = -log2(abs(dd$x[dd$x <0]))
#If number > 0 then take log2 of the number
dd$trans[dd$x> 0] = log2(dd$x[dd$x >0])
绘图前
boxplot(dd$trans)
我会创建一个名为 trans_log2
的函数来自动执行此操作,例如
dd$x = trans_log2(dd$x)
另一种方法是使用 $sign$ 函数,您仍然需要在单独的步骤中替换 0,例如
test <- rnorm(100)
abs_log <- function(x){
x[x==0] <- 1
si <- sign(x)
si * log2(si*x)
}
boxplot(abs_log(test))
让我们建设性地做到这一点:
如果 x > 0
我们记录它。
如果x == 0
我们用1替换它然后记录。
if x < 0
我们取反,然后记录,然后再次取反。也就是说,如果我们有负数,比如 x= -y, y>0
输出应该是 -1*log(y)
这正是 log(1/y)
.
的结果
所以我们想用 1/abs(x)
替换每个负面 x
,同时不损害我们的正面。显然 abs(x)
不会影响正数,表示负数的方式是它们的符号,由 sign(x)
给出。按符号求幂只会用它们的倒数替换负数。
总而言之,我们对值替换的解决方案是(abs(x))^(sign(x))
然后我们可以愉快地log2
,所以我们得到:
Log2Transformed <- log2((abs(df))^(sign(df)))
对于此输入(基于您的示例):
Open_TD Close_TD Invariant_TD
1 1.0 6 5
2 2.0 2 4
3 -32.0 0 -1
4 -0.5 0 2
5 NA 0 0
6 NA 0 1
我们得到以下输出:
Open_TD Close_TD Invariant_TD
[1,] 0 2.584963 2.321928
[2,] 1 1.000000 2.000000
[3,] -5 0.000000 0.000000
[4,] 1 0.000000 1.000000
[5,] NA 0.000000 0.000000
[6,] NA 0.000000 0.000000
一行,没有额外的功能,不需要实际更改原始数据或创建新的数据帧,最重要的是,它全部使用 R 和 MatLab 的典型矩阵脚本。
我有一个包含三列的矩阵,值有很多变化,从大的正值到 0 再到大的负值。为了更好地表示数据,我想取所有值的 log2,但由于不可能取负值和 0 的 log2,我想执行以下操作:
- 如果 number = 0 则将其更改为 1 并取 log2
- 如果数字 < 0 则取绝对值的 log2 并将负数赋给它
- 如果数字 > 0 则取数字的 log2
我正在尝试使用以下代码执行此操作,但到目前为止没有成功:
Log2Transformed <- ifelse(df == 0, 1, log2(df) & ifelse(df < 0, -log2(abs(df)), log2(df)))
head(df)
Open_TD Close_TD Invariant_TD
[1,] 1 6 5
[2,] 2 2 4
[3,] 0 0 -1
[4,] 0 0 2
[5,] NA 0 2
[6,] NA 0 1
可能有一些聪明的方法可以做到这一点,但我会花时间更清楚地定义每个步骤。
## Create dummy data
dd = data.frame(x = c(0, rnorm(100)))
首先为转换后的数据创建一列
dd$trans = dd$x
然后按照您的规则逐渐操作该列
#If number = 0 then change it to 1 and take log2
dd$trans[dd$x==0] = log2(1)
#If number < 0 then take log2 of absolute value
# and assign the negative number to it
dd$trans[dd$x< 0] = -log2(abs(dd$x[dd$x <0]))
#If number > 0 then take log2 of the number
dd$trans[dd$x> 0] = log2(dd$x[dd$x >0])
绘图前
boxplot(dd$trans)
我会创建一个名为 trans_log2
的函数来自动执行此操作,例如
dd$x = trans_log2(dd$x)
另一种方法是使用 $sign$ 函数,您仍然需要在单独的步骤中替换 0,例如
test <- rnorm(100)
abs_log <- function(x){
x[x==0] <- 1
si <- sign(x)
si * log2(si*x)
}
boxplot(abs_log(test))
让我们建设性地做到这一点:
如果 x > 0
我们记录它。
如果x == 0
我们用1替换它然后记录。
if x < 0
我们取反,然后记录,然后再次取反。也就是说,如果我们有负数,比如 x= -y, y>0
输出应该是 -1*log(y)
这正是 log(1/y)
.
所以我们想用 1/abs(x)
替换每个负面 x
,同时不损害我们的正面。显然 abs(x)
不会影响正数,表示负数的方式是它们的符号,由 sign(x)
给出。按符号求幂只会用它们的倒数替换负数。
总而言之,我们对值替换的解决方案是(abs(x))^(sign(x))
然后我们可以愉快地log2
,所以我们得到:
Log2Transformed <- log2((abs(df))^(sign(df)))
对于此输入(基于您的示例):
Open_TD Close_TD Invariant_TD
1 1.0 6 5
2 2.0 2 4
3 -32.0 0 -1
4 -0.5 0 2
5 NA 0 0
6 NA 0 1
我们得到以下输出:
Open_TD Close_TD Invariant_TD
[1,] 0 2.584963 2.321928
[2,] 1 1.000000 2.000000
[3,] -5 0.000000 0.000000
[4,] 1 0.000000 1.000000
[5,] NA 0.000000 0.000000
[6,] NA 0.000000 0.000000
一行,没有额外的功能,不需要实际更改原始数据或创建新的数据帧,最重要的是,它全部使用 R 和 MatLab 的典型矩阵脚本。