【问题标题】:Function to remove columns with max value less than a given value,删除最大值小于给定值的列的函数,
【发布时间】:2019-09-15 21:45:17
【问题描述】:

我正在使用数据框中的 34,000 列进行初始数据清理,为此,我必须删除最大值小于 2 的列。

我对如何删除最大值小于 2 的列一无所知,但为了获得最大值,我尝试创建如下函数而不使用 is.numeric 转换数据:

protein <- is.numeric(protein)
#a: 
colMax <- function(data) sapply(data, max, na.rm = TRUE)
colMax(protein)

我得到了对因子错误没有意义的最大值,这就是我使用 is.numeric 函数将所有数据转换为数字形式的原因。尽管如此,我仍然没有得到想要的结果。运行该函数时,我得到 0 作为结果,而不是每列的最大值列表。

为什么我的 max 函数为 0?如何设置一个函数,该函数可以为每列生成最大值并删除最大值小于 2 的任何列?我需要 2 个单独的函数吗?

【问题讨论】:

    标签: r max


    【解决方案1】:

    这是使用dplyr 选择max 值大于等于2 的列的另一种方法。假设我们要测试所有列并且所有这些列都属于factor 类。使用@Maurits 数据

    library(dplyr)
    
    df %>%
      #Convert column from factor to numeric
      mutate_all(~as.numeric(as.character(.))) %>%
      #Select column whose max value is greater than equal to 2 
      select_if(~max(., na.rm = TRUE) >= 2)
    
    
    #   V3 V4 V5 V6 V7 V8 V9 V10
    #1   3  4  5  6  7  8  9  10
    #2   3  4  5  6  7  8  9  10
    #3   3  4  5  6  7  8  9  10
    #4   3  4  5  6  7  8  9  10
    #5   3  4  5  6  7  8  9  10
    #6   3  4  5  6  7  8  9  10
    #7   3  4  5  6  7  8  9  10
    #8   3  4  5  6  7  8  9  10
    #9   3  4  5  6  7  8  9  10
    #10  3  4  5  6  7  8  9  10
    

    除了max,我们也可以使用any

    df %>%
      mutate_all(~as.numeric(as.character(.))) %>% 
      select_if(~any(. >= 2))
    

    你说你有 34000 列。您要检查所有列的大于 2 的条件吗?所有的列都是factors 吗?上面的代码检查所有列并选择不满足条件的列。如果您想对选定的列(不是全部)执行此操作,您可能需要对数据进行子集化,选择这些列,然后应用代码。


    在base R中,我们也可以在将数据从因子转换为数值后使用colSums

    df[] <- lapply(df, function(x) as.numeric(as.character(x)))
    df[, colSums(df >= 2) > 0]
    

    【讨论】:

    • 不,我的列数中缺少 6,它的 364000 列 - 有些是因素,有些不是。使用 lapply 是有效的,但有这么多数据,处理时间太长。上述方法会更快吗?
    • @Heena 我没有测试过,但colSums 方法应该更快。
    • 谢谢,我意识到我错过了参数 stringasfactors=False,这导致了处理的巨大延迟。但是一旦修好了,一切都解决了。
    【解决方案2】:

    你快到了。

    由于您不提供可重现的样本数据,我们首先创建一些最小的样本数据

    df <- as.data.frame(matrix(rep(1:10, each = 10), ncol = 10))
    df
    #   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
    #1   1  2  3  4  5  6  7  8  9  10
    #2   1  2  3  4  5  6  7  8  9  10
    #3   1  2  3  4  5  6  7  8  9  10
    #4   1  2  3  4  5  6  7  8  9  10
    #5   1  2  3  4  5  6  7  8  9  10
    #6   1  2  3  4  5  6  7  8  9  10
    #7   1  2  3  4  5  6  7  8  9  10
    #8   1  2  3  4  5  6  7  8  9  10
    #9   1  2  3  4  5  6  7  8  9  10
    #10  1  2  3  4  5  6  7  8  9  10
    

    我们现在只想保留max 值>2 的那些列;我们可以使用sapply来做到这一点

    df[sapply(df, function(x) max(x, na.rm = T) > 2)]
    #   V3 V4 V5 V6 V7 V8 V9 V10
    #1   3  4  5  6  7  8  9  10
    #2   3  4  5  6  7  8  9  10
    #3   3  4  5  6  7  8  9  10
    #4   3  4  5  6  7  8  9  10
    #5   3  4  5  6  7  8  9  10
    #6   3  4  5  6  7  8  9  10
    #7   3  4  5  6  7  8  9  10
    #8   3  4  5  6  7  8  9  10
    #9   3  4  5  6  7  8  9  10
    #10  3  4  5  6  7  8  9  10
    

    解释:sapply 循环遍历data.frame df 的列并返回一个logical 向量(与df 中的列一样多的条目)。


    或者我们可以使用pmaxapply

    df[apply(pmax(df) > 2, 2, all)]
    

    给出相同的结果。与第一种方法的不同之处在于pmax 返回一个matrix,我们使用apply(..., MARGIN = 2, ...) 在其上逐列操作。

    【讨论】:

    • 谢谢,我的数据类型问题仍然存在。运行上面的代码并使用 is.numeric 转换我的数据给我的结果为逻辑(0)。我的数据转换有问题吗?
    • @Heena - as.numeric 不能同时处理整个数据集。需要protein[] &lt;- lapply(protein, as.numeric) 之类的东西来覆盖原始数据。
    • 没有代表性的样本数据很难提供帮助。所以我需要在这里推测一下。看看我的例子。 data 必须是 data.frame,而不是列。也许您的转换问题源于您尝试将factor 转换为numeric 向量,在这种情况下尝试data$your_column &lt;- as.numeric(as.character(df$your_column))
    • @Heena 我对我的帖子进行了编辑,以包括一些进一步的解释。请看一看。
    猜你喜欢
    • 2022-11-14
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多