如何在 R 中截断多列
How to truncate multiple columns in R
我需要截断许多列以使其范围从 -3.0 到 3.0。这意味着:任何大于 +3.0 的值都应重新编码为 +3.0 到一个新变量中,所有小于 -3.0 的值也应重新编码到这个新变量中为 -3.0.
这是一个示例数据集
library(tidyverse)
MyData <- tibble( a = c(2.3, 3.0, -1.5, 3.7, -4.7, 5.2),
b = c(3.6, 1.52, -5.4, 4.6, 1.5, 2.2),
c = c(1.0, -2.6, -1.2, 2.5, -4.0, 3.0))
我找到了如何使用 mutate()
和 case_when()
为每个旧变量创建一个新变量,但是我有 太多变量无法手动完成,我想知道如何以更短、更优雅的方式做到这一点。我希望看到类似于源自此手动代码的输出:
MyData %>%
mutate(Ta = case_when(a >= 3.0 ~ 3.0,
a <= -3.0 ~ -3.0,
T ~ a),
Tb = case_when(b >= 3.0 ~ 3.0,
b <= -3.0 ~ -3.0,
T ~ b),
Tc = case_when(c >= 3.0 ~ 3.0,
c <= -3.0 ~ -3.0,
T ~ c))
# A tibble: 6 x 6
a b c Ta Tb Tc
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2.3 3.6 1 2.3 3 1
2 3 1.52 -2.6 3 1.52 -2.6
3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
4 3.7 4.6 2.5 3 3 2.5
5 -4.7 1.5 -4 -3 1.5 -3
6 5.2 2.2 3 3 2.2 3
您可以定义一个函数,然后使用 across
将其应用于许多列。
pmin(3, pmax(x, -3))
是一种将向量(即数据框的一列)限制在-3 到 3 范围内的方法。它取 x 和 -3 的最大值,然后取最小值结果和 3.
across
的 .names
参数让我们指定这些操作的结果应该是名为 T+[orig column name].
的附加列
cap3 <- function(x) { pmin(3, pmax(x, -3)) }
MyData %>%
mutate(across(a:c, cap3, .names = "T{.col}"))
# mutate(across(1:3, cap3, .names = "T{.col}")) # Equiv. alternative
# mutate(across(everything(), cap3, .names = "T{.col}")) # Equiv. alternative
结果
# A tibble: 6 x 6
a b c Ta Tb Tc
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2.3 3.6 1 2.3 3 1
2 3 1.52 -2.6 3 1.52 -2.6
3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
4 3.7 4.6 2.5 3 3 2.5
5 -4.7 1.5 -4 -3 1.5 -3
6 5.2 2.2 3 3 2.2 3
转换为矩阵,获取 pmin 和 pmax 并将其附加到 MyData。
(虽然示例不需要,但如果存在只应处理某些列的情况,则在 as.matrix 之前的管道中插入适当的 select 语句,例如 select(1:2) 或 select(a:b) 到 select 前两列或 select(where(is.numeric)) 到 select 只有数字列。)
MyData %>%
as.matrix %>%
pmin(3) %>%
pmax(-3) %>%
cbind(MyData, T = .)
给予:
a b c T.a T.b T.c
1 2.3 3.60 1.0 2.3 3.00 1.0
2 3.0 1.52 -2.6 3.0 1.52 -2.6
3 -1.5 -5.40 -1.2 -1.5 -3.00 -1.2
4 3.7 4.60 2.5 3.0 3.00 2.5
5 -4.7 1.50 -4.0 -3.0 1.50 -3.0
6 5.2 2.20 3.0 3.0 2.20 3.0
在函数中编写要应用到每一列的代码,然后用 across
应用它。
library(dplyr)
func <- function(a) {
case_when(a >= 3.0 ~ 3.0,
a <= -3.0 ~ -3.0,
T ~ a)
}
MyData %>%
mutate(across(.fns = func, .names = 'T{col}'))
# a b c Ta Tb Tc
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 2.3 3.6 1 2.3 3 1
#2 3 1.52 -2.6 3 1.52 -2.6
#3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
#4 3.7 4.6 2.5 3 3 2.5
#5 -4.7 1.5 -4 -3 1.5 -3
#6 5.2 2.2 3 3 2.2 3
我需要截断许多列以使其范围从 -3.0 到 3.0。这意味着:任何大于 +3.0 的值都应重新编码为 +3.0 到一个新变量中,所有小于 -3.0 的值也应重新编码到这个新变量中为 -3.0.
这是一个示例数据集
library(tidyverse)
MyData <- tibble( a = c(2.3, 3.0, -1.5, 3.7, -4.7, 5.2),
b = c(3.6, 1.52, -5.4, 4.6, 1.5, 2.2),
c = c(1.0, -2.6, -1.2, 2.5, -4.0, 3.0))
我找到了如何使用 mutate()
和 case_when()
为每个旧变量创建一个新变量,但是我有 太多变量无法手动完成,我想知道如何以更短、更优雅的方式做到这一点。我希望看到类似于源自此手动代码的输出:
MyData %>%
mutate(Ta = case_when(a >= 3.0 ~ 3.0,
a <= -3.0 ~ -3.0,
T ~ a),
Tb = case_when(b >= 3.0 ~ 3.0,
b <= -3.0 ~ -3.0,
T ~ b),
Tc = case_when(c >= 3.0 ~ 3.0,
c <= -3.0 ~ -3.0,
T ~ c))
# A tibble: 6 x 6
a b c Ta Tb Tc
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2.3 3.6 1 2.3 3 1
2 3 1.52 -2.6 3 1.52 -2.6
3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
4 3.7 4.6 2.5 3 3 2.5
5 -4.7 1.5 -4 -3 1.5 -3
6 5.2 2.2 3 3 2.2 3
您可以定义一个函数,然后使用 across
将其应用于许多列。
pmin(3, pmax(x, -3))
是一种将向量(即数据框的一列)限制在-3 到 3 范围内的方法。它取 x 和 -3 的最大值,然后取最小值结果和 3.
across
的 .names
参数让我们指定这些操作的结果应该是名为 T+[orig column name].
cap3 <- function(x) { pmin(3, pmax(x, -3)) }
MyData %>%
mutate(across(a:c, cap3, .names = "T{.col}"))
# mutate(across(1:3, cap3, .names = "T{.col}")) # Equiv. alternative
# mutate(across(everything(), cap3, .names = "T{.col}")) # Equiv. alternative
结果
# A tibble: 6 x 6
a b c Ta Tb Tc
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2.3 3.6 1 2.3 3 1
2 3 1.52 -2.6 3 1.52 -2.6
3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
4 3.7 4.6 2.5 3 3 2.5
5 -4.7 1.5 -4 -3 1.5 -3
6 5.2 2.2 3 3 2.2 3
转换为矩阵,获取 pmin 和 pmax 并将其附加到 MyData。
(虽然示例不需要,但如果存在只应处理某些列的情况,则在 as.matrix 之前的管道中插入适当的 select 语句,例如 select(1:2) 或 select(a:b) 到 select 前两列或 select(where(is.numeric)) 到 select 只有数字列。)
MyData %>%
as.matrix %>%
pmin(3) %>%
pmax(-3) %>%
cbind(MyData, T = .)
给予:
a b c T.a T.b T.c
1 2.3 3.60 1.0 2.3 3.00 1.0
2 3.0 1.52 -2.6 3.0 1.52 -2.6
3 -1.5 -5.40 -1.2 -1.5 -3.00 -1.2
4 3.7 4.60 2.5 3.0 3.00 2.5
5 -4.7 1.50 -4.0 -3.0 1.50 -3.0
6 5.2 2.20 3.0 3.0 2.20 3.0
在函数中编写要应用到每一列的代码,然后用 across
应用它。
library(dplyr)
func <- function(a) {
case_when(a >= 3.0 ~ 3.0,
a <= -3.0 ~ -3.0,
T ~ a)
}
MyData %>%
mutate(across(.fns = func, .names = 'T{col}'))
# a b c Ta Tb Tc
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 2.3 3.6 1 2.3 3 1
#2 3 1.52 -2.6 3 1.52 -2.6
#3 -1.5 -5.4 -1.2 -1.5 -3 -1.2
#4 3.7 4.6 2.5 3 3 2.5
#5 -4.7 1.5 -4 -3 1.5 -3
#6 5.2 2.2 3 3 2.2 3