扩展数据帧中的数字序列

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

数据让我们看一个简单的数据集(我的实际上是> 200,000行):

df <- data.frame(
  id = c(rep(1, 11), rep(2,6)),
  ref.pos = c(NA,NA,NA,301,302,303,800,801,NA,NA,NA, 500,501,502, NA, NA, NA),
  pos     = c(1:11, 30:35)
)

哪个看起来像这样:

   id ref.pos pos
1   1      NA   1
2   1      NA   2
3   1      NA   3
4   1     301   4
5   1     302   5
6   1     303   6
7   1     800   7
8   1     801   8
9   1      NA   9
10  1      NA  10
11  1      NA  11
12  2     500  30
13  2     501  31
14  2     502  32
15  2      NA  33
16  2      NA  34
17  2      NA  35

我想实现什么对于id,我想扩展ref.pos中的数字以填充整列,其中ref.pos数字在数据框中向下移动,在列中向下移动。这将导致以下数据框:

   id ref.pos pos
1   1     298   1
2   1     299   2
3   1     300   3
4   1     301   4
5   1     302   5
6   1     303   6
7   1     800   7
8   1     801   8
9   1     802   9
10  1     803  10
11  1     804  11
12  2     500  30
13  2     501  31
14  2     502  32
15  2     503  33
16  2     504  34
17  2     505  35

我尝试了什么我希望可以在此处提供一些代码,但是两天内我仍未找到正确的方法,尤其是不适用于大型数据集的方法。我发现df %>% group_by(id) %>% tidyr::fill(ref.pos, .direction = "downup")很有趣,但是这是重复数字,而不是对我而言是反复上升的。

我希望我的问题很清楚,否则请在评论中让我知道!

r dataframe range numeric
2个回答
1
投票

使用data.table的选项:

fillends <- function(x) nafill(nafill(x, "locf"), "nocb")

setDT(df)[, ref.pos2 := {
    dif <- fillends(c(diff(ref.pos), NA_integer_))
    frp <- fillends(ref.pos)
    fp <- fillends(replace(pos, is.na(ref.pos), NA_integer_))
    fifelse(is.na(ref.pos), frp + dif*(pos - fp), ref.pos)
}, id]

输出:

    id ref.pos pos ref.pos2
 1:  1      NA   1      298
 2:  1      NA   2      299
 3:  1      NA   3      300
 4:  1     301   4      301
 5:  1     302   5      302
 6:  1     303   6      303
 7:  1     802   7      802
 8:  1     801   8      801
 9:  1      NA   9      800
10:  1      NA  10      799
11:  1      NA  11      798
12:  2     500  30      500
13:  2     501  31      501
14:  2     502  32      502
15:  2      NA  33      503
16:  2      NA  34      504
17:  2      NA  35      505

数据:

df <- data.frame(
    id = c(rep(1, 11), rep(2,6)),
    ref.pos = c(NA,NA,NA,301,302,303,802,801,NA,NA,NA, 500,501,502, NA, NA, NA),
    pos     = c(1:11, 30:35)
)

1
投票

一个基本的R选项是定义自定义功能fill,将在ave中应用

fill <- function(v) {
  inds <- range(which(!is.na(v)))
  l <- 1:inds[1]
  u <- inds[2]:length(v)
  v[l] <- v[inds[1]] - rev(l)+1
  v[u] <- v[inds[2]] + seq_along(u)-1
  v
}

df <- within(df,ref.pos <- ave(ref.pos,id,FUN = fill))

诸如此类

> df
   id ref.pos pos
1   1     298   1
2   1     299   2
3   1     300   3
4   1     301   4
5   1     302   5
6   1     303   6
7   1     800   7
8   1     801   8
9   1     802   9
10  1     803  10
11  1     804  11
12  2     500  30
13  2     501  31
14  2     502  32
15  2     503  33
16  2     504  34
17  2     505  35
© www.soinside.com 2019 - 2024. All rights reserved.