简体   繁体   中英

Conditional mutate_at and lag

Based on a extension of this question , I have a tidy tibble with several "nested groups" where some of them contain a NA in the last row.

# A tibble: 16 x 9
# Groups:   VP, Con, Dir [2]
      VP   Con   Dir   Seg time_seg mean_v_seg sd_v_seg mean_abs_v_seg sd_abs_v_seg
   <int> <int> <int> <int>    <int>      <dbl>    <dbl>          <dbl>        <dbl>
 1    10     2     1     1     1810      233.     142.           233.         142. 
 2    10     2     1     2      260      105.      77.0          105.          77.0
 3    10     2     1     3      540      158.      98.0          158.          98.0
 4    10     2     1     4     1470      219.     125.           219.         125. 
 5    10     2     1     5      460      359.     233.           359.         233. 
 6    10     2     1     6      690      281.     149.           281.         149. 
 7    10     2     1     7      760      599.     281.           599.         281. 
 8    10     2     1     8       NA       NA       NA             NA           NA  
 9    10     2     2     1      320       88.0    103.            88.0        103. 
10    10     2     2     2     1110      183.      75.3          183.          75.3
11    10     2     2     3      450       40.6     44.4           40.6         44.4
12    10     2     2     4      600       67.8     53.7           67.8         53.7
13    10     2     2     5     1680      178.     107.           178.         107. 
14    10     2     2     6      730      227.      99.2          227.          99.2
15    10     2     2     7      850      224.     192.           224.         192. 
16    10     2     2     8      840      463.     243.           463.         243.

I now noticed, that for these groups, the NA should actually be in the first row instead of the last row. Therefore, I was thinking about using lag to move the data in the columns between time_seg and sd_abs_v_seg on row further down using an in place replacement (I don't want new columns).

The desired output would therefore be

# A tibble: 16 x 9
# Groups:   VP, Con, Dir [2]
      VP   Con   Dir   Seg time_seg mean_v_seg sd_v_seg mean_abs_v_seg sd_abs_v_seg
   <int> <int> <int> <int>    <int>      <dbl>    <dbl>          <dbl>        <dbl>
 1    10     2     1     1       NA       NA       NA             NA           NA 
 2    10     2     1     2     1810      233.     142.           233.         142. 
 3    10     2     1     3      260      105.      77.0          105.          77.0
 4    10     2     1     4      540      158.      98.0          158.          98.0 
 5    10     2     1     5     1470      219.     125.           219.         125. 
 6    10     2     1     6      460      359.     233.           359.         233. 
 7    10     2     1     7      690      281.     149.           281.         149. 
 8    10     2     1     8      760      599.     281.           599.         281.  
 9    10     2     2     1      320       88.0    103.            88.0        103. 
10    10     2     2     2     1110      183.      75.3          183.          75.3
11    10     2     2     3      450       40.6     44.4           40.6         44.4
12    10     2     2     4      600       67.8     53.7           67.8         53.7
13    10     2     2     5     1680      178.     107.           178.         107. 
14    10     2     2     6      730      227.      99.2          227.          99.2
15    10     2     2     7      850      224.     192.           224.         192. 
16    10     2     2     8      840      463.     243.           463.         243.

I was thinking about using mutate together with an ifelse parameter, however, then I would have to specify every column where the replacement shall take place. Therefore, I was thinking about using mutate_at - vars() together with ifelse (which should check if this group is complete). Something like this comes close, however, it also generates new columns (which I don't want). Is there a functionality in dplyr that would solve this?

Below is the dput to reproduce.

structure(list(VP = c(10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
    10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L), Con = c(2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), Dir = c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
        Seg = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 
        6L, 7L, 8L), time_seg = c(1810L, 260L, 540L, 1470L, 460L, 
        690L, 760L, NA, 320L, 1110L, 450L, 600L, 1680L, 730L, 850L, 
        840L), mean_v_seg = c(232.726734030707, 104.655087869347, 
        157.902075043105, 219.283376258725, 359.45973673094, 280.549706434598, 
        599.424071456088, NA, 87.9826401741796, 182.735676197134, 
        40.6448541145307, 67.7977476910328, 177.773637255357, 227.483717669439, 
        224.429379556985, 462.826739492667), sd_v_seg = c(141.879040585992, 
        77.0389438694476, 97.9539089123486, 125.076162880904, 233.204343193672, 
        149.049291752719, 280.885009497318, NA, 102.904347085381, 
        75.3257592307251, 44.4481451785732, 53.7088336445736, 106.75027532838, 
        99.2415032284702, 192.206130493083, 243.219568282535), mean_abs_v_seg = c(232.726734030707, 
        104.655087869347, 157.902075043105, 219.283376258725, 359.45973673094, 
        280.549706434598, 599.424071456088, NA, 87.9826401741796, 
        182.735676197134, 40.6448541145307, 67.7977476910328, 177.773637255357, 
        227.483717669439, 224.429379556985, 462.826739492667), sd_abs_v_seg = c(141.879040585992, 
        77.0389438694476, 97.9539089123486, 125.076162880904, 233.204343193672, 
        149.049291752719, 280.885009497318, NA, 102.904347085381, 
        75.3257592307251, 44.4481451785732, 53.7088336445736, 106.75027532838, 
        99.2415032284702, 192.206130493083, 243.219568282535)), row.names = c(NA, 
    -16L), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), vars = c("VP", 
    "Con", "Dir"), drop = TRUE, indices = list(0:7, 8:15), group_sizes = c(8L, 
    8L), biggest_group_size = 8L, labels = structure(list(VP = c(10L, 
    10L), Con = c(2L, 2L), Dir = 1:2), row.names = c(NA, -2L), class = "data.frame", vars = c("VP", 
    "Con", "Dir"), drop = TRUE))

Base

I actually found a solution myself.

data %>%
  mutate_at(vars(time_seg:sd_abs_v_seg), funs(if(anyNA(.))
                                                lag(., 1)
                                              else
                                                .))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM