R 在mutate_中按名称片段引用其他列

R 在mutate_中按名称片段引用其他列,r,dplyr,R,Dplyr,为了可视化问题,我们假设R中有一个数据集data,包含以下列: 因素 param T1_g1 T2_g1 T1_g2 T2_g2 我想对列的子集执行操作: data\u final% 在(变量T1,T2),funs(如果(参数>100)处突变{ *T(n)\u g1 }否则{ *T(n)\u g2 } 如何在表达式T(n)\u g1中引用正确的列名,以便在变异时分别从T1\u g1和T2\u g1获取数据 (在真实案例场景中,我有更多的列和条件,因此手动键入所有可能的案例不是一个选项)如

为了可视化问题,我们假设R中有一个数据集
data
,包含以下列:

  • 因素
  • param
  • T1_g1
  • T2_g1
  • T1_g2
  • T2_g2
我想对列的子集执行操作:

data\u final%
在(变量T1,T2),funs(如果(参数>100)处突变{
*T(n)\u g1
}否则{
*T(n)\u g2
} 
如何在表达式
T(n)\u g1
中引用正确的列名,以便在变异时分别从
T1\u g1
T2\u g1
获取数据


(在真实案例场景中,我有更多的列和条件,因此手动键入所有可能的案例不是一个选项)

如果需要单个比较,但由于这将是一个向量,您需要
如果else
(或
如果else
)。我不知道您可以(轻松地)根据quick
mutate*
界面中待更改的名称动态确定其他列名。快速破解可能是:

data %>%
  mutate(
    T1 = if_else(param > 100, T1_g1, T1_g2) * T1,
    T2 = if_else(param > 100, T2_g1, T2_g2) * T2
  )
但是,只有当您有一个小的/静态的
T*
变量列表要修改时,这才有效

如果这些
T*
变量的数量是动态的(或者只是“高”),那么一种方法包括将帧重塑为更长的格式(有人可能会认为长格式可能更适合这种情况,所以我将逐步介绍宽-长变异和宽-长变异-宽)

一些数据:

x <- data_frame(
  param = c(1L,50L,101L,150L),
  T1 = 1:4,
  T2 = 5:8,
  T1_g1 = (1:4)/10,
  T1_g2 = (1:4)*10,
  T2_g1 = (5:8)/10,
  T2_g2 = (5:8)*10
)
x
# # A tibble: 4 x 7
#   param    T1    T2 T1_g1 T1_g2 T2_g1 T2_g2
#   <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
# 1     1     1     5   0.1    10   0.5    50
# 2    50     2     6   0.2    20   0.6    60
# 3   101     3     7   0.3    30   0.7    70
# 4   150     4     8   0.4    40   0.8    80
整形后,您最初的
mutate_at
概念将简化为一个
mutate(T=…)
调用。其余部分包括重新水合宽度


如果您的数据很大,这可能会有点麻烦。其他解决方案可能包括手动确定
T#
列和手动执行
ifelse
(在
mutate
之外).

这样的列有两个以上的
T1
T2
,或者你是在试图概括这两个列吗?如果只有两个,最简单的解决方案可能是
If.\u else
变异
。我正在尝试概括-这样的列有很多。感谢下面的答案,@r2evans!非常感谢@r2evans的c全面的回答!重塑数据的想法确实是一个很好的方法。
x %>%
  gather(k, v, -param) %>%
  mutate(
    num = sub("^T([0-9]+).*", "\\1", k),
    k   = sub("^T[0-9]+(.*)", "T\\1", k)
  ) %>%
  spread(k, v)
# # A tibble: 8 x 5
#   param num       T  T_g1  T_g2
#   <int> <chr> <dbl> <dbl> <dbl>
# 1     1 1         1   0.1    10
# 2     1 2         5   0.5    50
# 3    50 1         2   0.2    20
# 4    50 2         6   0.6    60
# 5   101 1         3   0.3    30
# 6   101 2         7   0.7    70
# 7   150 1         4   0.4    40
# 8   150 2         8   0.8    80
x %>%
  gather(k, v, -param) %>%
  mutate(
    num = sub("^T([0-9]+).*", "\\1", k),
    k   = sub("^T[0-9]+(.*)", "T\\1", k)
  ) %>%
  spread(k, v) %>%
  mutate(T = T * if_else(param > 100, T_g1, T_g2)) %>%
  gather(k, v, -param, -num) %>%
  mutate(k = if_else(grepl("^T", k), paste0("T", num, substr(k, 2, nchar(k))), k)) %>%
  select(-num) %>%
  spread(k, v)
# # A tibble: 4 x 7
#   param     T1 T1_g1 T1_g2     T2 T2_g1 T2_g2
#   <int>  <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl>
# 1     1 10       0.1    10 250      0.5    50
# 2    50 40       0.2    20 360      0.6    60
# 3   101  0.900   0.3    30   4.90   0.7    70
# 4   150  1.6     0.4    40   6.4    0.8    80