关于 r:由列定义的范围内数据框行的总和


Sum of data frame's rows in range defined by columns

我有一个基于整数的数据框,其中一列中的位置坐标和第二列中的变量。坐标范围为 1-1000 万,变量范围为 0-950 - 我有兴趣返回在包含所需范围的起点和终点的单独框架内定义的范围内的变量总和。

为了使计算更容易,我缩短了示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Data:
a = seq(1,5)
b = c(0,0,1,0,2)
df1 <- data.frame(a, b)

c = c(1,1,2,2,3)
d = c(3,4,3,5,4)
df2 <- data.frame(c,d)

df1:
1, 0
2, 0
3, 1
4, 0
5, 2

df2:
1, 3
1, 4
2, 3
2, 5
3, 4

魔法

1
2
3
4
5
6
output:
1,
1,
1,
3,
1,

魔法是将 df2 第 1 列和第 2 列中的开始和结束位置传递给 rowSums 以进行 df1 提取。


编辑:@Frank 的 data.table 解决方案:短而快。

1
2
3
4
5
6
7
8
9
df2[, s := df1[df2, on=.(a >= c, a <= d), sum(b), by=.EACHI]$V1]

    # output
       c d s
    1: 1 3 1
    2: 1 4 1
    3: 2 3 1
    4: 2 5 3
    5: 3 4 1

另一种方式(可能较慢但有效):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
library(data.table)
setDT(df1)
setDT(df2)

## magic function
get_magic <- function(x)
{
    spell <- c()

    one <- unlist(x[1])
    two <- unlist(x[2])

    a <- df1[between(a, one, two), sum(b)]
    spell <- append(spell, a)

    return(spell)

}


# applies to row
d <- apply(df2, 1, get_magic)

print(d)
# output
[1] 1 1 1 3 1


一种可能的解决方案是使用 mapply。我使用了一个自定义函数,但可以编写一个内联函数作为 mapply 语句的一部分。

1
2
3
4
5
6
7
8
mapply(row_sum, df2$c, df2$d)

row_sum <- function(x, y){
  sum(df1[x:y,2])
}

#Result
#[1] 1 1 1 3 1

数据

1
2
3
4
5
6
7
a = seq(1,5)
b = c(0,0,1,0,2)
df1 <- data.frame(a, b)

c = c(1,1,2,2,3)
d = c(3,4,3,5,4)
df2 <- data.frame(c,d)