R跨越并使用两个动态命名的列来计算结果

R mutate across and using two dynamically named columns to calculate result

Test <- tribble(~Date, ~HCl_Konz, ~HCl_Kenn, ~CO_Konz, ~CO_Kenn,
                   1, 4, "", 4, "",
                   2, 5, "", 1, "",
                   3, 2, "X", 6, "BX",
                   4, 5, "", 4, "",
                   5, 6, "F", 4, "",
                   6, 5, "", 9, "EXr")
Param <- c("HCl", "CO")

真正的 tibble 更大,有几列,如 HCl 和 CO,但它们都遵循相同的方案。对于所有这些列,我想将 HCl_Konz 的值设置为 NA,如果列 HCl_Kenn 至少有一个字符“X”或“F”,与 [=22= 相同](如果 CO_Kenn 包含 X 或 F),以及所有其他 XXX_Konz 列。

我尝试了以下代码,但它因以下错误而退出。

Test %>% rowwise() %>%
    mutate(across(paste(Param, "_Konz", sep=""), ~ ifelse(str_detect(paste(str_sub(cur_column(),1,-6), "_Kenn", sep=""), "[XF]"), NA_real_, .x)))

代码没有抛出错误,但值没有被 NA 替换。

蒂亚

  1. 您缺少 ~ 来将 ifelse(..) 标记为排序函数。
  2. cur_col() 未找到(对我而言),应该是 ..x
  3. str_detect 使用 _Kenn 等效列的名称,而不是该列中的值;我们还需要添加 cur_data()[[..]]

我倾向于不使用 stringr 作为 straight-forward 这样的替换,更喜欢基础 R:

library(dplyr)
Test %>%
  mutate(
    across(
      paste0(Param, "_Konz"),
      ~ if_else( grepl("[XF]", cur_data()[[ gsub("_Konz", "_Kenn", cur_column()) ]] ),
                .[NA], . )
    )
  )
# # A tibble: 6 x 5
#    Date HCl_Konz HCl_Kenn CO_Konz CO_Kenn
#   <dbl>    <dbl> <chr>      <dbl> <chr>  
# 1     1        4 ""             4 ""     
# 2     2        5 ""             1 ""     
# 3     3       NA "X"           NA "BX"   
# 4     4        5 ""             4 ""     
# 5     5       NA "F"            4 ""     
# 6     6        5 ""            NA "EXr"  

出于多种原因,我建议使用 dplyr::if_else 代替 ifelse,但它附带了 true=false= 参数的严格(且安全!)要求是完全相同的类型。您至少通过使用 NA_real_ 认识到其中的大部分内容;我对 .[NA] 的使用是确保我们根据实际数据获得正确 NA-变体的另一种方法,如果您的某些 Params 是 [=29=,则允许此方法起作用],有些是 numeric,例如

另一种方法(稍后可能会有所帮助)是旋转数据并一次只处理两列。

library(tidyr) # pivot_longer
Test %>%
  pivot_longer(
    matches("_(Konz|Kenn)$"),
    names_pattern = "(.*)_(.*)", names_to = c("elem", ".value")
  ) %>%
  mutate(
    Konz = if_else(grepl("[XF]", Kenn), Konz[NA], Konz)
  )
# # A tibble: 12 x 4
#     Date elem   Konz Kenn 
#    <dbl> <chr> <dbl> <chr>
#  1     1 HCl       4 ""   
#  2     1 CO        4 ""   
#  3     2 HCl       5 ""   
#  4     2 CO        1 ""   
#  5     3 HCl      NA "X"  
#  6     3 CO       NA "BX" 
#  7     4 HCl       5 ""   
#  8     4 CO        4 ""   
#  9     5 HCl      NA "F"  
# 10     5 CO        4 ""   
# 11     6 HCl       5 ""   
# 12     6 CO       NA "EXr"

这种旋转格式的优点是可以更简单地调用 mutate,并且(如果您打算绘制此图)更适合 ggplot2 对长数据的偏好。