【问题标题】:conditionally copying reference values in r有条件地复制 r 中的参考值
【发布时间】:2022-01-06 15:31:29
【问题描述】:

我正在尝试根据参考值有条件地将 x 列中的值复制到新列中。例如在第 1 行中,对于 time == 1ref 的值为 7,因此 newx 值应从 time == 1id == 7 复制 x 值,复制的值始终需要位于同一时间块中。

如果ref 的值为0,则newx 的值也应为0

我已经尝试了几种方法,下面可能是我所达到的最接近的方法,但它仍然无法正常工作

        library(dplyr)
        x <- sample(1:50, 24)
        y <- sample(1:50, 24)
        ref <- c(7,7,7,7,0,0,0,0,0,0,0,0,4,3,4,1,8,8,5,8,0,0,0,0)
        id <- rep(seq(1,8,1), 3)
        time <- rep(1:3, each = 8)

    x  y ref id time
1  41 29   7  1    1
2  18 37   7  2    1
3  50 25   7  3    1
4  47  7   7  4    1
5   2 40   0  5    1
6  22 19   0  6    1
7  48  9   0  7    1
8  26 36   0  8    1
9  49 47   0  1    2
10 46 18   0  2    2
11 25 23   0  3    2
12 38  3   0  4    2
13 28 31   4  5    2
14 34  4   3  6    2
15 21 32   4  7    2
16  9 48   1  8    2
17 43 43   8  1    3
18 39 38   8  2    3
19  6 16   5  3    3
20 12 41   8  4    3
21  1 13   0  5    3
22 19 17   0  6    3
23  7 34   0  7    3
24 33 10   0  8    3

        
        df <- as.data.frame(cbind(x,y,ref,id,time))
        
        df <- df %>% group_by(time) %>% mutate(Newx = case_when((ref > 0) ~ x[which(id==ref)],
                                                              T ~ 0,))

【问题讨论】:

  • 我有点困惑。你有id == 7,但它从不等于7。你的意思是ref吗?你也有id == ref。在您的示例中,这绝不是真的。
  • 我现在在数据集中添加了一个示例表。所以在上面的例子中,newx 将在前 4 行(48、48、48、48)中复制 id 7 的 x 值,然后接下来的四个将是 0,这将在时间 1 结束,然后在时间 2 开始再有 4 个 0,然后是 id 4,即 38,然后是 id 3,即 25。希望这是有道理的

标签: r dplyr reference copy conditional-statements


【解决方案1】:

你可以自己加入 df。最后的变异只是删除 ref == 0 行的 NA。您也可以使用tidyr::replace_na,但我想坚持只使用 dplyr:

df %>%
  left_join(df %>% select(x, id, time) %>% rename(newx = x), by= c("time", "ref" = "id")) %>%
  mutate(newx = ifelse(is.na(newx), 0, newx))

哪些结果:

    x  y ref id time newx
1  44 44   7  1    1   36
2  37 26   7  2    1   36
3  40 27   7  3    1   36
4  32 46   7  4    1   36
5  48 33   0  5    1    0
6  31  6   0  6    1    0
7  36  1   0  7    1    0
8  27 11   0  8    1    0
9  26 32   0  1    2    0
10 42 22   0  2    2    0
11 22 21   0  3    2    0
12 15 28   0  4    2    0
13 45 47   4  5    2   15
14 49  4   3  6    2   22
15 25 50   4  7    2   15
16 14  3   1  8    2   26
17 13 42   8  1    3   12
18 38  7   8  2    3   12
19 10 12   5  3    3   50
20  2 40   8  4    3   12
21 50 43   0  5    3    0
22  4  9   0  6    3    0
23 34 49   0  7    3    0
24 12 31   0  8    3    0

【讨论】:

    【解决方案2】:

    使用purrr::map_dbl 你可以这样做:

    library(purrr)
    library(dplyr)
    
    df %>%
      group_by(time) %>%
      mutate(newx = map_dbl(ref, function(ref) if (ref > 0) .data$x[.data$id == ref] else 0)) %>% 
      ungroup()
    #> # A tibble: 24 × 6
    #>        x     y   ref    id  time  newx
    #>    <int> <int> <dbl> <dbl> <int> <dbl>
    #>  1    31    17     7     1     1    37
    #>  2    15    43     7     2     1    37
    #>  3    14    39     7     3     1    37
    #>  4     3    12     7     4     1    37
    #>  5    42    15     0     5     1     0
    #>  6    43    32     0     6     1     0
    #>  7    37    42     0     7     1     0
    #>  8    48     7     0     8     1     0
    #>  9    25     9     0     1     2     0
    #> 10    26    41     0     2     2     0
    #> # … with 14 more rows
    

    数据

    set.seed(123)
    
    x <- sample(1:50, 24)
    y <- sample(1:50, 24)
    ref <- c(7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 1, 8, 8, 5, 8, 0, 0, 0, 0)
    id <- rep(seq(1, 8, 1), 3)
    time <- rep(1:3, each = 8)
    
    df <- data.frame(x, y, ref, id, time)
    

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      相关资源
      最近更新 更多