在数据框中应用日志功能[关闭]

问题描述 投票:2回答:2

我正在尝试通过应用日志转换来更改R中数据框内的值。

我的数据框只包含数值。当我应用此功能

logFunct <- function(x) log10(x)
dim(data.frame(logFunct(df))

一切运作良好(即20列和20行数据帧将返回20列和20行新数据帧)。

但是,当我试图用这个函数来计算零值时(我知道,它可能是一个丑陋的函数):

log4Zero <- function(x) ifelse(x!=0, log10(x+0.00000000001), log10(1))
dim(data.frame(log4Zero(df))

我有400列×20行,零值被捕获为非零(返回-11而不是0)。

任何人都可以请解释这里发生了什么,我该如何解决这个问题(即零值为零,其他任何添加和记录)?

r function vectorization transformation logarithm
2个回答
0
投票

如果你能提供一个例子,那就太好了。但是,如果我已经很好地理解了这个问题,那么data.frame会减少它的尺寸。根据我在下面放置的示例,不应该发生。第二个功能是正确的。我举一个如何应用它的例子,所以没有问题。希望有所帮助:

library(tidyverse)

set.seed(123)

df <- as.data.frame(matrix(c(0, sample(0:14, size = 14)), ncol = 5))

df %>% 
  mutate_all(., ~ ifelse(.!=0, log10(.+0.00000000001), log10(1)))

0
投票

对于Rui Barradas上面回答的+1,请使用log1p

非常重要的是要注意 - 上面的解决方案仅返回log(x+1),初始分数为0,log(x+1e-11)返回其他所有内容。这给你:

log4Zero(0) ~= log4Zero(1)
log4Zero(0) >> log4Zero(1e-10)

0比1更接近1e-10但是在转换之后,你对0的观察将远远高于你对1e-10的观察。我几乎可以肯定这不是你想要的。

使用一些虚拟数据:

df = data.frame(matrix(rnorm(400,5,1), nrow=20))
df[1,1] = 0
df[2,1] = 1e-10
log1p(df)

当我运行log4Zero(df)时,它返回一个长度为400的列表,而不是数据帧。这是因为ifelse()已经被矢量化了。因此,如果您将整个数据框传递给它,则不会将x作为数据框的每个条目,而是每列。从r维度c的数据框中,它将返回长度为r * c的列表,每个条目都是转换列(log10(x+0.00000000001))或单个值(log10(1)

如果您确实想使用ifelse()应用函数,请改用apply()

logNew = function(x) ifelse(x!=0, log10(x), NA)
apply(df, 2, logNew)
© www.soinside.com 2019 - 2024. All rights reserved.