快速对 R 内的值进行分箱

问题描述 投票:0回答:1

我在 R 中有一个巨大的数据框,看起来像这样:

数据框1

身份证 开始 停止
+ 3 5
- 9 13

我还有另一个数据框,看起来像这样:

数据框2

身份证 名字 位置
- 你好 4
+ 那里 7
- 我的 11
+ 名字 12

我想要做的是对于数据帧 1 中的每一行,我想确定它在给定范围内的“距离”,或者如果它不属于某个范围或“ID”(+/-) 不属于某个范围,则打印 NA匹配。所以输出会是这样的:

身份证 名字 位置 相对位置
- 你好 4 2
+ 那里 7 不适用
- 我的 12 3
+ 名字 12 不适用

我目前有一个相对较长的循环,使用 apply() 和几层 if 函数来运行这个过程。我遇到的问题是我需要对多个非常大的数据帧(大小为千兆字节)执行此操作,因此效率是关键。完成这个过程最有效的方法是什么?

我也尝试过 cut() 函数,但我不知道如何打印我想要的结果或如何使间隔不连续。即使它有效,我也不知道它是否会更有效。

r dataframe apply
1个回答
0
投票

主要是判断多个位置是否处于区间的问题。这是一个算法问题。

这是一种有效的算法来查找所有位置的包含间隔。我将距离的计算和结果的正确格式留在练习中;-)(从这个画布上应该很容易)。

library(data.table)

## DF1
intervals <- data.table(id = c('+', '-'),
                        start = c(3, 9),
                        end = c(5, 13))

## DF2
values <- data.table(id = c('-', '+', '-', '+'),
                     name = c("hello", "there", "my", "name"),
                     pos = c(4, 7, 12, 12))

## The trick is to sort by position everything,
## `type` is 0 if it is an interval start position,
##           1 = interval end position, and
##           2 = is a position in `values`
## `id` is the index (row number) either in `intervals` or `values`
n.interval <- nrow(intervals)
dt <- rbind(data.table(id = 1:n.interval, pos = intervals$start, type = 0),
            data.table(id = 1:n.interval, pos = intervals$end, type = 1),
            data.table(id = 1:nrow(values), pos = values$pos, type = 2))
setorder(dt, pos)
len <- nrow(dt)

## A stack that will contain the interval row number
depth <- 0
stack <- numeric(16384)

## loop over the rows of `dt`                     
for (i in 1:len)
{
    if ( 0 == dt$type[i] ) ## start
    {
        depth <- depth + 1
        ## add on stack the row numbre of the interval
        stack[depth] <- dt$id[i]
    }
    else if ( 1 == dt$type[i] && 0 < depth ) ## end
    {
        ## pop from the stack
        depth <- depth - 1
    }
    else if ( 2 == dt$type[i]) ## Value
    {
        cat("=====\nThe value:\n")
        value.id <- dt$id[i]
        print(values[value.id,])
        if ( 0 < depth )
        {
            ## the intervals on the `stack` all contain the current value
            index <- stack[depth]
            cat("\nis inside this interval (most imbricated):\n")
            print(intervals[index,])
        } else {
            cat("\nis outside any interval\n\n")
        }
    } else {
        warning("should not be here")
        break
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.