R按组过滤值填入新列。

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

我想在我的 dat,由满足条件的值填写。所以,我想保留 value 哪儿 regime == "SA" 并将此值填入新的列中,覆盖整个组。vals.sa.

这结合了 filtermutate但我不确定它们的正确组合是什么?Filter 只是保持满足条件的行,但我如何将这个值扩展到组中的所有行?

我的数据。

dat <- data.frame(id = c(1,1,2,2,2,2,3,3),
                  regime = c("SA", "B", "SA", "B", "C", "F", "SA", "D"),
                  value = c(3,5,1,2,5,6,7,8))

用以下方法处理数据 dplyr

dat %>% 
  # group data by id
  group_by(id) %>%           
  # how to write this condition and get values instead or TRUE/FALSE?
  mutate(val.sa = regime == "SA") 

填写后的预期产出 val.sa 对应 regime == "SA"

     id regime value val.sa
  <dbl> <fct>  <dbl>  <dbl>
1     1 SA         3      3
2     1 B          5      3
3     2 SA         1      1
4     2 B          2      1
5     2 C          5      1
6     2 F          6      1
7     3 SA         7      7
8     3 D          8      7
r filter dplyr expand
2个回答
4
投票

你可以使用.NET技术。

library(dplyr)
dat %>%
  group_by(id) %>%
  mutate(value.sa = value[regime == 'SA'])
  #OR
  #mutate(value.sa = value[match('SA', regime)])


#     id regime value value.sa
#  <dbl> <chr>  <dbl>    <dbl>
#1     1 SA         3        3
#2     1 B          5        3
#3     2 SA         1        1
#4     2 B          2        1
#5     2 C          5        1
#6     2 F          6        1
#7     3 SA         7        7
#8     3 D          8        7

如果可以有一个以上的 regime 归属 "SA",您可以使用 which.maxmatch.

dat %>%
  group_by(id) %>%
  mutate(value.sa = value[which.max(regime == 'SA')])

3
投票

如果你总是只有一个 SA 在每个组中,这应该不会出现任何错误。

dat %>% 
  group_by(id) %>%             
  mutate(val.sa = value[regime == "SA"]) 
#> # A tibble: 8 x 4
#> # Groups:   id [3]
#>      id regime value val.sa
#>   <dbl> <fct>  <dbl>  <dbl>
#> 1     1 SA         3      3
#> 2     1 B          5      3
#> 3     2 SA         1      1
#> 4     2 B          2      1
#> 5     2 C          5      1
#> 6     2 F          6      1
#> 7     3 SA         7      7
#> 8     3 D          8      7

否则,你将不得不决定哪个 SA-你想保留的值。例如,始终保持最大值。

dat <- data.frame(id = c(1,1,2,2,2,2,3,3),
                  regime = c("SA", "B", "SA", "SA", "C", "F", "SA", "D"),
                  value = c(3,5,1,2,5,6,7,8))
dat
#>   id regime value
#> 1  1     SA     3
#> 2  1      B     5
#> 3  2     SA     1
#> 4  2     SA     2
#> 5  2      C     5
#> 6  2      F     6
#> 7  3     SA     7
#> 8  3      D     8

dat %>% 
  group_by(id) %>%             
  mutate(val.sa = max(value[regime == "SA"]))
#> # A tibble: 8 x 4
#> # Groups:   id [3]
#>      id regime value val.sa
#>   <dbl> <fct>  <dbl>  <dbl>
#> 1     1 SA         3      3
#> 2     1 B          5      3
#> 3     2 SA         1      2
#> 4     2 SA         2      2
#> 5     2 C          5      2
#> 6     2 F          6      2
#> 7     3 SA         7      7
#> 8     3 D          8      7

2
投票

创建一个新的列 val.sa 中的值,先用 SA 中的值的行数。value 列。然后按 idfill 下。像这样。

dat %>%
  mutate(val.sa = ifelse(regime == 'SA', value, NA)) %>%
  group_by(id) %>%
  fill(val.sa)
## A tibble: 8 x 4
## Groups:   id [3]
#     id regime value val.sa
#  <dbl> <chr>  <dbl>  <dbl>
#1     1 SA         3      3
#2     1 B          5      3
#3     2 SA         1      1
#4     2 B          2      1
#5     2 C          5      1
#6     2 F          6      1
#7     3 SA         7      7
#8     3 D          8      7

1
投票

我们可以用 case_when

library(dplyr)
library(tidyr)
 dat %>%
     mutate(val.sa = case_when(regime == 'SA' ~ value) %>%
     group_by(id) %>%
     fill(val.sa)
© www.soinside.com 2019 - 2024. All rights reserved.