改变行的子集,但使用 dplyr 保留所有行

Mutate a subset of rows, but keep all rows with dplyr

如何使用 dplyr 将人口列乘以 -1,仅针对性别“kvinnor”?

下面是将 population 列中的所有值相乘的代码:

df %>% 
  mutate(neg_kv = population*-1)
# data
df <- tibble::tribble(
     ~region, ~marriage_status, ~age,   ~gender, ~population, ~year,
     "Riket",         "ogifta",   15,     "män",       56031,  1968,
     "Riket",         "ogifta",   15, "kvinnor",       52959,  1968,
     "Riket",         "ogifta",   16,     "män",       55917,  1968,
     "Riket",         "ogifta",   16, "kvinnor",       52979,  1968,
     "Riket",         "ogifta",   17,     "män",       55922,  1968,
     "Riket",         "ogifta",   17, "kvinnor",       52050,  1968,
     "Riket",         "ogifta",   18,     "män",       58681,  1968,
     "Riket",         "ogifta",   18, "kvinnor",       51862,  1968,
     "Riket",         "ogifta",   19,     "män",       60387,  1968,
     "Riket",         "ogifta",   19, "kvinnor",       49750,  1968,
     "Riket",         "ogifta",   20,     "män",       62487,  1968,
     "Riket",         "ogifta",   20, "kvinnor",       50089,  1968,
     "Riket",         "ogifta",   21,     "män",       60714,  1968,
     "Riket",         "ogifta",   21, "kvinnor",       43413,  1968,
     "Riket",         "ogifta",   22,     "män",       56801,  1968,
     "Riket",         "ogifta",   22, "kvinnor",       36301,  1968,
     "Riket",         "ogifta",   23,     "män",       49862,  1968,
     "Riket",         "ogifta",   23, "kvinnor",       29227,  1968,
     "Riket",         "ogifta",   24,     "män",       42143,  1968,
     "Riket",         "ogifta",   24, "kvinnor",       23155,  1968
     )

您需要一个 ifelse 语句来识别 gender == kvinnor

library(dplyr)

df %>% mutate(neg_kv = ifelse(gender == "kvinnor", -1 * population, population))

# A tibble: 20 × 7
   region marriage_status   age gender  population  year neg_kv
   <chr>  <chr>           <dbl> <chr>        <dbl> <dbl>  <dbl>
 1 Riket  ogifta             15 män          56031  1968  56031
 2 Riket  ogifta             15 kvinnor      52959  1968 -52959
 3 Riket  ogifta             16 män          55917  1968  55917
 4 Riket  ogifta             16 kvinnor      52979  1968 -52979
 5 Riket  ogifta             17 män          55922  1968  55922
 6 Riket  ogifta             17 kvinnor      52050  1968 -52050
 7 Riket  ogifta             18 män          58681  1968  58681
 8 Riket  ogifta             18 kvinnor      51862  1968 -51862
 9 Riket  ogifta             19 män          60387  1968  60387
10 Riket  ogifta             19 kvinnor      49750  1968 -49750
11 Riket  ogifta             20 män          62487  1968  62487
12 Riket  ogifta             20 kvinnor      50089  1968 -50089
13 Riket  ogifta             21 män          60714  1968  60714
14 Riket  ogifta             21 kvinnor      43413  1968 -43413
15 Riket  ogifta             22 män          56801  1968  56801
16 Riket  ogifta             22 kvinnor      36301  1968 -36301
17 Riket  ogifta             23 män          49862  1968  49862
18 Riket  ogifta             23 kvinnor      29227  1968 -29227
19 Riket  ogifta             24 män          42143  1968  42143
20 Riket  ogifta             24 kvinnor      23155  1968 -23155

base R中,我们可以做到

df$neg_kv <-  c(1, -1)[(df$gender == "kvinnor") + 1] * df$population

为了好玩,这里有另外两种替代方法:

  1. dplyr + purrr:
library(dplyr)
library(purrr)
df %>%
  mutate(id = row_number()) %>% 
  mutate(neg_kv = population) %>% 
  group_split(gender == "kvinnor", .keep=FALSE) %>% 
  modify_at(2, ~ mutate(., neg_kv = population * -1)) %>% 
  bind_rows() %>% 
  arrange(id) %>% 
  select(-id)
  1. base R:使用索引:
index <- df$gender == "kvinnor"
df$neg_kv <- df$population
df$neg_kv[index] <- df$population[index] *-1
df

输出:

   region marriage_status   age gender  population  year neg_kv
   <chr>  <chr>           <dbl> <chr>        <dbl> <dbl>  <dbl>
 1 Riket  ogifta             15 män          56031  1968  56031
 2 Riket  ogifta             15 kvinnor      52959  1968 -52959
 3 Riket  ogifta             16 män          55917  1968  55917
 4 Riket  ogifta             16 kvinnor      52979  1968 -52979
 5 Riket  ogifta             17 män          55922  1968  55922
 6 Riket  ogifta             17 kvinnor      52050  1968 -52050
 7 Riket  ogifta             18 män          58681  1968  58681
 8 Riket  ogifta             18 kvinnor      51862  1968 -51862
 9 Riket  ogifta             19 män          60387  1968  60387
10 Riket  ogifta             19 kvinnor      49750  1968 -49750
11 Riket  ogifta             20 män          62487  1968  62487
12 Riket  ogifta             20 kvinnor      50089  1968 -50089
13 Riket  ogifta             21 män          60714  1968  60714
14 Riket  ogifta             21 kvinnor      43413  1968 -43413
15 Riket  ogifta             22 män          56801  1968  56801
16 Riket  ogifta             22 kvinnor      36301  1968 -36301
17 Riket  ogifta             23 män          49862  1968  49862
18 Riket  ogifta             23 kvinnor      29227  1968 -29227
19 Riket  ogifta             24 män          42143  1968  42143
20 Riket  ogifta             24 kvinnor      23155  1968 -23155