有条件地复制 r 中的参考值

conditionally copying reference values in r

我正在尝试根据参考值有条件地将 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,))

使用 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)

你可以自己加入df。最后一个 mutate 只是删除 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