首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在第二列中的值实例之间查找一列的累积和

在第二列中的值实例之间查找一列的累积和
EN

Stack Overflow用户
提问于 2021-08-04 15:10:37
回答 3查看 89关注 0票数 2

我有一个数据框,看起来像这样;

代码语言:javascript
复制
df <- data.frame(Trip =c(rep("A",10),rep("B",10)), 
                 State =c(0,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,1,1,1,0),
                 Distance = c(0,2,9,4,3,1,4,5,6,3,2,6,1,5,3,3,6,1,8,2), 
                 DistanceToNext = c(NA,NA,NA,3,1,15,NA,NA,NA,NA,NA,1,17,NA,NA,NA,1,8,NA,NA)) 

   Trip State Distance DistanceToNext
1  A 0 1  NA
2  A 0 2  NA
3  A 0 9  NA
4  A 1 4   3
5  A 1 3   1
6  A 1 1  15
7  A 0 4  NA
8  A 0 5  NA
9  A 1 6  NA
10 A 0 3  NA
11 B 0 2  NA
12 B 1 6   1
13 B 1 1  17
14 B 0 5  NA
15 B 0 3  NA
16 B 0 3  NA
17 B 1 6   1
18 B 1 1   8
19 B 1 8  NA
20 B 0 2  NA

状态列指示捕鱼船是在钓鱼(状态= 1)还是不在钓鱼(状态= 0)。我想计算每个钓鱼事件之间的距离(State = 1)。

距离列表示该行位置与前一行之间的距离(例如,它是滞后距离)。

DistanceToNext列是我试图生成的答案,对于Trip中的所有行,它都应该是NA,直到钓鱼状态= 1的第一行。对于此行,DistanceToNext应该等于后续行的距离列的总和,直到下一个钓鱼状态= 1。

例如,第4行是行程A中的第一个钓鱼事件(状态= 1),DistanceToNext单元格应该是下一个钓鱼事件之前行进的距离,在他的情况下是距离为3的下一行(第5行)。

对于第5行,下一个钓鱼事件再次是下一行(第6行),距离为1。但是,对于第6行,我们看到直到第9行才有另一个钓鱼事件,所以我需要6和9之间的行的d列的累积和为15。

如果它是它的x分组(A或B)中的最后一行State =1,那么就没有另一个钓鱼事件,所以没有要计算的距离,所以我希望它给出NA

EN

回答 3

Stack Overflow用户

发布于 2021-08-04 16:56:26

在base R中,你可以这样做:

代码语言:javascript
复制
fun <- function(df){
    a <- which(df$State == 1)
    b <- rep(NA, nrow(df))
    d <- mapply(function(x, y) sum(df$Distance[(x+1):y]), head(a,-1), tail(a, -1))
    b[a] <- c(d, NA)
    transform(df, DisttoNext = b)
}

do.call(rbind, by(df, df$Trip, fun))
     Trip State Distance DistanceToNext DisttoNext
A.1     A     0        0             NA         NA
A.2     A     0        2             NA         NA
A.3     A     0        9             NA         NA
A.4     A     1        4              3          3
A.5     A     1        3              1          1
A.6     A     1        1             15         15
A.7     A     0        4             NA         NA
A.8     A     0        5             NA         NA
A.9     A     1        6             NA         NA
A.10    A     0        3             NA         NA
B.11    B     0        2             NA         NA
B.12    B     1        6              1          1
B.13    B     1        1             17         17
B.14    B     0        5             NA         NA
B.15    B     0        3             NA         NA
B.16    B     0        3             NA         NA
B.17    B     1        6              1          1
B.18    B     1        1              8          8
B.19    B     1        8             NA         NA
B.20    B     0        2             NA         NA
票数 2
EN

Stack Overflow用户

发布于 2021-08-05 06:10:54

这是另一个你可以使用的解决方案。我还对每个组中的每个State/ Distance向量使用了一个自定义函数,以产生所需的输出:

代码语言:javascript
复制
fn <- function(State, Distance) {
  out <- rep(NA, length(State))
  
  inds <- which(State == 1)
  for(i in inds) {
    if(State[i] == 1 & State[i + 1] == 1) {
      out[i] <- Distance[i + 1]
    } else if (State[i] == 1 & State[i + 1] == 0 & i != inds[length(inds)]) {
      nx <- which(inds == i)
      out[i] <- sum(Distance[(i+1):(inds[nx + 1])])
    } else {
      NA
    }
  }
  out
}

df %>%
  group_by(Trip) %>%
  mutate(MyDistance = fn(State, Distance))

# A tibble: 20 x 5
# Groups:   Trip [2]
   Trip  State Distance DistanceToNext MyDistance
   <chr> <dbl>    <dbl>          <dbl>      <dbl>
 1 A         0        0             NA         NA
 2 A         0        2             NA         NA
 3 A         0        9             NA         NA
 4 A         1        4              3          3
 5 A         1        3              1          1
 6 A         1        1             15         15
 7 A         0        4             NA         NA
 8 A         0        5             NA         NA
 9 A         1        6             NA         NA
10 A         0        3             NA         NA
11 B         0        2             NA         NA
12 B         1        6              1          1
13 B         1        1             17         17
14 B         0        5             NA         NA
15 B         0        3             NA         NA
16 B         0        3             NA         NA
17 B         1        6              1          1
18 B         1        1              8          8
19 B         1        8             NA         NA
20 B         0        2             NA         NA
票数 2
EN

Stack Overflow用户

发布于 2021-08-05 18:05:44

data.table替代方案。

代码语言:javascript
复制
library(data.table)
setDT(df)

df[,`:=`(next_dist = shift(Distance, type = "lead"), g = cumsum(State), ri = .I),
   by = Trip]     
d = df[ , .(ri = ri[1], State = State[1], s = sum(next_dist)), by = .(Trip, g)]
df[d[State == 1, .SD[-.N], by = Trip], on = .(ri), s := s]
df[ , `:=`(ri = NULL, next_dist = NULL, g = NULL)]

#     Trip State Distance DistanceToNext  s
#  1:    A     0        0             NA NA
#  2:    A     0        2             NA NA
#  3:    A     0        9             NA NA
#  4:    A     1        4              3  3
#  5:    A     1        3              1  1
#  6:    A     1        1             15 15
#  7:    A     0        4             NA NA
#  8:    A     0        5             NA NA
#  9:    A     1        6             NA NA
# 10:    A     0        3             NA NA
# 11:    B     0        2             NA NA
# 12:    B     1        6              1  1
# 13:    B     1        1             17 17
# 14:    B     0        5             NA NA
# 15:    B     0        3             NA NA
# 16:    B     0        3             NA NA
# 17:    B     1        6              1  1
# 18:    B     1        1              8  8
# 19:    B     1        8             NA NA
# 20:    B     0        2             NA NA

解释:

将数据转换为data.table (setDT(df))。

对于每个'Trip‘(by = Trip),通过引用创建新的变量(:=):next distance (shift(Distance, type = "lead")),一个分组变量,它在每次'State’为1时增加(cumsum(State)),一个用于连接结果的行索引(.I;这也可以先完成,不需要分组)。

对于每个'Trip‘和'State group’(by = .(Trip, g)),选择first row index (ri[1]),first 'State‘(State = State[1]),并对引线距离(sum(next_dist))求和。

从上面的结果中,选择“状态”为1 (State == 1)的行。然后,对于每个'Trip‘(by = Trip),选择除最后一行(-.N)之外的数据子集(.SD)。连接到行索引(on = .(ri))上的原始数据。创建一个新列,sum of distances,'s‘by reference (:=)。如果需要,可以删除temp变量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68653741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档