【问题标题】:Calculation on a vector of values in a R data.table计算 R data.table 中的值向量
【发布时间】:2021-08-09 11:14:15
【问题描述】:

我在 R 中有以下 data.table:

dataset <- data.table(C=c("a", "b", "c") , neg=c("5, 7", "9", "3, 4, 5"), pos = c("5.05, 8", "", "2.95, 4.2"))

表格如下所示:

我想找到“neg”和“pos”列中的值之间的重叠。 如果同一行中两列中的任何值之间的差异小于 0.1 - 我想通过取两个值的平均值来合并这些值。 例如。对于第 5 对和 5.05 – 5.025 应计算。如果在相同的 0.1 范围内没有值,则仅显示原始值。我添加了一张我对可能结果的想法的图片:

是否有直接执行此操作的功能,还是我必须先拆分/重新排列表格?

感谢您的帮助!

【问题讨论】:

    标签: r datatable aggregate data-wrangling


    【解决方案1】:

    数字存储为字符值,因此首先您需要将它们以逗号分隔,将它们转换为数字,sort 数据。然后,您可以计算连续值之间的差值,如果它们的差值小于 0.1,则将两个值合并(通过取它们的平均值)。

    在基础 R 中,使用 Maptapply 你可以做到 -

    dataset$overlap <- Map(function(x, y) {
      p <- sort(as.numeric(c(x, y)))
      as.numeric(tapply(p, cumsum(c(TRUE, diff(p) > 0.1)), mean))
    }, strsplit(dataset$neg, ',\\s*'), strsplit(dataset$pos, ',\\s*'))
    
    dataset
    
    #   C     neg       pos                 overlap
    #1: a    5, 7   5.05, 8       5.025,7.000,8.000
    #2: b       9                                 9
    #3: c 3, 4, 5 2.95, 4.2 2.975,4.000,4.200,5.000
    
    dataset$overlap
    
    #[[1]]
    #[1] 5.025 7.000 8.000
    
    #[[2]]
    #[1] 9
    
    #[[3]]
    #[1] 2.975 4.000 4.200 5.000
    

    【讨论】:

    • 谢谢!它看起来很完美。
    【解决方案2】:

    在问题的示例中,任何输入单元格中都没有 0.1 范围内的值,我们假设这是一般情况,如果不是,那么也可以合并这些值。

    对于每一行,将数字扫描成一个数字向量,对其进行排序并找到相邻数字小于 0.1 的实例。取这些数字的平均值,然后 NA 去掉之前的数字。省略 NA 并转换为逗号分隔的字符串。

    如果 C 中的值是唯一的,那么我们可以将 by= 替换为 by=C。

    dataset[, overlap := {
      s <- sort(scan(text = c(neg, pos), sep = ",", quiet = TRUE))
      wx <- which(c(FALSE, diff(s) < 0.1))
      s[wx] <- (s[wx] + s[wx-1]) / 2
      s[wx-1] <- NA
      toString(na.omit(s))
    }, by = 1:nrow(dataset)]
    
    dataset
    ##    C     neg       pos          overlap
    ## 1: a    5, 7   5.05, 8      5.025, 7, 8
    ## 2: b       9                          9
    ## 3: c 3, 4, 5 2.95, 4.2 2.975, 4, 4.2, 5
    

    【讨论】:

    • 谢谢!你是对的:在一个输入单元格中,没有任何值在 0.1 范围内(就在 pos/neg cols 之间)。一个问题:如何在您的代码中使用列的名称(pos/neg)?我试图替换 apply 函数中的 1/-1 但它不起作用。对于示例代码,它运行良好!
    • 已将其修改为使用 pos 和 neg 并删除应用。我不明白评论中提到 1/-1 的部分。
    • 好的!谢谢 - 现在它也适用于 col。名字。
    猜你喜欢
    • 2012-10-28
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    相关资源
    最近更新 更多