如何创建IF并在R中运行[duplicate]

2uluyalo  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(98)
    • 此问题在此处已有答案**:

Update a Value in One Column Based on Criteria in Other Columns(4个答案)
5天前关闭。
我想创建一个基于现有列的值生成新列的函数。
以下示例:

day1  weight1
20       .
25      190
26      167
27      189
28      200
60      300
120     127

条件-〉如果第1天〉20且第1天〈200,则weightAdj = weight1;(代码摘自SAS)
输出:

day1  weight1  weightAdj
20       .       .
25      190      190
26      167      167
27      189      189
28      200      NA
60      300      NA
120     127      127

有人能帮帮我吗?

jaxagkaj

jaxagkaj1#

我们可以使用dplyr::if_else()或基r ifelse()函数,我假设你指的是weight1 < 200而不是day1 < 200,为什么weightAdj25行而不是190行?

library(dplyr)

dat %>% 
  mutate(weightAdj = if_else(day1 > 20 & weight1 < 200, weight1, NA_real_))

#> # A tibble: 7 x 3
#>    day1 weight1 weightAdj
#>   <dbl>   <dbl>     <dbl>
#> 1    20      NA        NA
#> 2    25     190       190
#> 3    26     167       167
#> 4    27     189       189
#> 5    28     200        NA
#> 6    60     300        NA
#> 7   120     127       127

来自OP的数据:

dat <- tribble(
  ~day1,  ~weight1,
20  ,     NA,
25  ,    190,
26  ,    167,
27  ,    189,
28  ,    200,
60  ,    300,
120 ,    127)

如果你有很多列对要应用ifelse函数,那么我们有几种方法,如下所示:

library(dplyr)

dat <- tribble(
  ~day1,  ~weight1, ~day2, ~weight2,
  20  ,     NA,  40,     180,
  25  ,    190,  18,     210,
  26  ,    167,  25,     350,
  27  ,    189,  30,     150,
  28  ,    200,  50,     175,
  60  ,    300,  65,      80,
  120 ,    127,  15,      50,
  )

# dplyr only approach:
# works with columns in any order
dat %>% 
  mutate(across(starts_with("weight"),
                .fns = ~ if_else(get(sub("^\\w+(\\d+)$", "day\\1", cur_column())) > 20 & .x < 200, .x, NA_real_),
                .names = "{.col}Adj")
         )

#> # A tibble: 7 x 6
#>    day1 weight1  day2 weight2 weight1Adj weight2Adj
#>   <dbl>   <dbl> <dbl>   <dbl>      <dbl>      <dbl>
#> 1    20      NA    40     180         NA        180
#> 2    25     190    18     210        190         NA
#> 3    26     167    25     350        167         NA
#> 4    27     189    30     150        189        150
#> 5    28     200    50     175         NA        175
#> 6    60     300    65      80         NA         80
#> 7   120     127    15      50        127         NA

library(dplyover) # https://timteafan.github.io/dplyover/

# using `dplyover::across2()`
# aussumes columns are in correct order 1, 2, 3 ...

dat %>% 
  mutate(across2(starts_with("weight"),
                 starts_with("day"),
                 .fns = ~ if_else(.y > 20 & .x < 200, .x, NA_real_),
                .names = "{xcol}Adj")
  )

#> # A tibble: 7 x 6
#>    day1 weight1  day2 weight2 weight1Adj weight2Adj
#>   <dbl>   <dbl> <dbl>   <dbl>      <dbl>      <dbl>
#> 1    20      NA    40     180         NA        180
#> 2    25     190    18     210        190         NA
#> 3    26     167    25     350        167         NA
#> 4    27     189    30     150        189        150
#> 5    28     200    50     175         NA        175
#> 6    60     300    65      80         NA         80
#> 7   120     127    15      50        127         NA

# using `dplyover::over()`
# works with column in any order
dat %>% 
  mutate(over(cut_names("^[A-z]+"), # <- returns `c("1", "2")`,
                 .fns = ~ if_else(.("day{.x}") > 20 & .("weight{.x}") < 200,
                                  .("weight{.x}"),
                                  NA_real_),
                 .names = "weight{x}Adj")
  )

#> # A tibble: 7 x 6
#>    day1 weight1  day2 weight2 weight1Adj weight2Adj
#>   <dbl>   <dbl> <dbl>   <dbl>      <dbl>      <dbl>
#> 1    20      NA    40     180         NA        180
#> 2    25     190    18     210        190         NA
#> 3    26     167    25     350        167         NA
#> 4    27     189    30     150        189        150
#> 5    28     200    50     175         NA        175
#> 6    60     300    65      80         NA         80
#> 7   120     127    15      50        127         NA

reprex package(v2.0.1)于2023年2月27日创建

相关问题