繁体   English   中英

如何将cross()函数与mutate()和case_when()结合起来,根据条件对多列中的值进行变异?

[英]How to combine the across () function with mutate () and case_when () to mutate values in multiple columns according to a condition?

我有人口统计数据集,其中包括家庭成员的年龄。 这是通过调查收集的,参与者可以拒绝提供他们的年龄。

结果是一个数据集,每行一个家庭(每个家庭都有一个家庭 ID 代码),列中有各种家庭特征,例如年龄。 拒绝响应编码为“R”,您可以使用以下代码重新创建示例:

df <- list(Household_ID = c("1A", "1B", "1C", "1D", "1E"),
           AGE1 = c("25", "47", "39", "50", "R"),
           AGE2 = c("66", "23", "71", "R", "16"),
           AGE3 = c("28", "17", "R", "R", "80"),
           AGE4 = c("81", "22", "48", "59", "R"))

df <- as_tibble(df)

> df
# A tibble: 5 x 5
  Household_ID AGE1  AGE2  AGE3  AGE4 
  <chr>        <chr> <chr> <chr> <chr>
1 1A           25    66    28    81   
2 1B           47    23    17    22   
3 1C           39    71    R     48   
4 1D           50    R     R     59   
5 1E           R     16    80    R 

出于我们的意图和目的,我们将“R”重新编码为“-9”,以便我们随后可以将 AGE 列的格式转换为整数,并进行分析。 我们通常在另一个软件中这样做,我的目标是在 R 中复制这个过程。

我设法使用以下代码做到了这一点:

df <- df %>% mutate(AGE1 = case_when(AGE1 == "R" ~ "-9", TRUE ~ as.character(AGE1)))
df <- df %>% mutate(AGE2 = case_when(AGE2 == "R" ~ "-9", TRUE ~ as.character(AGE2)))
df <- df %>% mutate(AGE3 = case_when(AGE3 == "R" ~ "-9", TRUE ~ as.character(AGE3)))
df <- df %>% mutate(AGE4 = case_when(AGE4 == "R" ~ "-9", TRUE ~ as.character(AGE4)))

鉴于这感觉很笨拙,我尝试使用 mutate_if 等找到解决方案,但读到这些已被 cross() 取代。 因此,我尝试使用 cross() 复制此操作:

df <- df %>%
  mutate(across(AGE1:AEG4),
          ~ (case_when(. == "R" ~ "-9")))

但我收到以下错误:

Error: Problem with `mutate()` input `..2`.
x Input `..2` must be a vector, not a `formula` object.
i Input `..2` is `~(case_when(. == "R" ~ "-9"))`.

一直在努力解决这个问题并在谷歌上搜索了一段时间,但无法弄清楚我错过了什么。 非常感谢有关如何使其工作的一些意见,谢谢。

编辑:解决了!

df <- df %>%
  mutate(across(AGE1:AGE4, ~ (case_when(.x == "R" ~ "-9", TRUE ~ as.character(.x)))))

为什么不简单?

df[,2:5][df[, 2:5] == 'R'] <- '-9'

# A tibble: 5 x 5
  Household_ID AGE1  AGE2  AGE3  AGE4 
  <chr>        <chr> <chr> <chr> <chr>
1 1A           25    66    28    81   
2 1B           47    23    17    22   
3 1C           39    71    -9    48   
4 1D           50    -9    -9    59   
5 1E           -9    16    80    -9

或者也许这与亲爱的@TarJae 的解释没有太大区别:

library(dplyr)
library(stringr)


df %>%
  mutate(across(AGE1:AGE4, ~ str_replace(., "R", "-9")),
         across(AGE1:AGE4, as.integer))

# A tibble: 5 x 5
  Household_ID  AGE1  AGE2  AGE3  AGE4
  <chr>        <int> <int> <int> <int>
1 1A              25    66    28    81
2 1B              47    23    17    22
3 1C              39    71    -9    48
4 1D              50    -9    -9    59
5 1E              -9    16    80    -9

数据:

df <- list(Household_ID = c("1A", "1B", "1C", "1D", "1E"),
           AGE1 = c("25", "47", "39", "50", "R"),
           AGE2 = c("66", "23", "71", "R", "16"),
           AGE3 = c("28", "17", "R", "R", "80"),
           AGE4 = c("81", "22", "48", "59", "R"))

df <- as_tibble(df)

您可以将acrossreplace一起replace

  1. 使用as_tibble()进行as_tibble()列表
  2. 用 -9 替换 R
  3. AGE 的整数类
df %>% 
  as_tibble() %>% 
  mutate(across(everything(), ~replace(., . ==  "R" , "-9"))) %>% 
  type.convert(as.is=TRUE)

输出:

  Household_ID  AGE1  AGE2  AGE3  AGE4
  <chr>        <int> <int> <int> <int>
1 1A              25    66    28    81
2 1B              47    23    17    22
3 1C              39    71    -9    48
4 1D              50    -9    -9    59
5 1E              -9    16    80    -9

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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