如何将函数应用于函数中向量中列出的多个列
How to apply a function to several columns listed in a vector in a function
在一个函数中,我试图为数据框创建一个附加列,它对应于函数条目中列出的其他几个列的最小值。
最小数据集为:
C1 <- c(1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0)
C2 <- c(0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0)
C3 <- c(0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1)
C4 <- c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
Data <- data.frame(C1, C2, C3, C4)
如果我想要 C1、C2 和 C4 中的最小值,在函数外,我会调用:
Data$Min <- pmin(Data$C1, Data$C2, Data$C4)
然而,在一个函数中,我挣扎并且只能产生这个:
min.col <- function(data, conditions){
data$Min <- pmin(data[[conditions]]) # [[ ]] is the wrong way to refer to the conditions, but I do not find how to
# After that, I go on here with my function based on the column data$Min but it is not relevant for the present problem.
}
呼叫者:
min.col(data, conditions=c("C1", "C2", "C4"))
有人帮忙吗?非常感谢!
这些仅使用基础 R。
1)我们可以这样使用do.call("pmin", ...)
。
f <- function(data, cols) transform(data, min = do.call("pmin", data[cols]))
f(Data, c("C1", "C2", "C4"))
给予:
C1 C2 C3 C4 min
1 1 0 0 0 0
2 0 1 1 0 0
3 1 1 0 0 0
4 1 1 0 1 1
5 0 0 0 0 0
6 0 1 0 0 0
7 1 0 1 0 0
8 1 0 1 1 0
9 0 0 1 0 0
10 0 1 0 0 0
11 0 1 1 0 0
12 1 1 1 1 1
13 1 0 0 0 0
14 0 1 0 0 0
15 0 0 1 0 0
2) 或使用 apply
f2 <- function(data, cols) transform(data, min = apply(data[cols], 1, min))
f2(Data, c("C1", "C2", "C4"))
3) 或 Reduce
f3 <- function(data, cols) transform(data, min = Reduce(pmin, data[cols]))
f3(Data, c("C1", "C2", "C4"))
4) 如果 data[cols] 只有 0 和 1 个单元格,那么如果我们计算一行中 0 的数量,那么如果总和为 0,则最小值应该为 1否则最小值为 0。请注意,当强制转换为逻辑值时,0 被视为 FALSE,任何其他数字都被视为 TRUE:
f4 <- function(data, cols) transform(data, min = +!rowSums(!data[cols]))
f4(Data, c("C1", "C2", "C4"))
我们可以使用 tidyverse
包中的一些函数快速完成此操作。这里的关键是不使用引号,将列包裹在vars
中,然后在函数中使用三重爆炸!!!
分隔和计算。
library(tidyverse)
min.col <- function(data, conditions){
data %>%
mutate(Min = pmin(!!!conditions))
}
min.col(Data, vars(C1, C2))
#> C1 C2 C3 C4 Min
#> 1 1 0 0 0 0
#> 2 0 1 1 0 0
#> 3 1 1 0 0 1
#> 4 1 1 0 1 1
#> 5 0 0 0 0 0
#> 6 0 1 0 0 0
#> 7 1 0 1 0 0
#> 8 1 0 1 1 0
#> 9 0 0 1 0 0
#> 10 0 1 0 0 0
#> 11 0 1 1 0 0
#> 12 1 1 1 1 1
#> 13 1 0 0 0 0
#> 14 0 1 0 0 0
#> 15 0 0 1 0 0
在一个函数中,我试图为数据框创建一个附加列,它对应于函数条目中列出的其他几个列的最小值。
最小数据集为:
C1 <- c(1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0)
C2 <- c(0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0)
C3 <- c(0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1)
C4 <- c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
Data <- data.frame(C1, C2, C3, C4)
如果我想要 C1、C2 和 C4 中的最小值,在函数外,我会调用:
Data$Min <- pmin(Data$C1, Data$C2, Data$C4)
然而,在一个函数中,我挣扎并且只能产生这个:
min.col <- function(data, conditions){
data$Min <- pmin(data[[conditions]]) # [[ ]] is the wrong way to refer to the conditions, but I do not find how to
# After that, I go on here with my function based on the column data$Min but it is not relevant for the present problem.
}
呼叫者:
min.col(data, conditions=c("C1", "C2", "C4"))
有人帮忙吗?非常感谢!
这些仅使用基础 R。
1)我们可以这样使用do.call("pmin", ...)
。
f <- function(data, cols) transform(data, min = do.call("pmin", data[cols]))
f(Data, c("C1", "C2", "C4"))
给予:
C1 C2 C3 C4 min
1 1 0 0 0 0
2 0 1 1 0 0
3 1 1 0 0 0
4 1 1 0 1 1
5 0 0 0 0 0
6 0 1 0 0 0
7 1 0 1 0 0
8 1 0 1 1 0
9 0 0 1 0 0
10 0 1 0 0 0
11 0 1 1 0 0
12 1 1 1 1 1
13 1 0 0 0 0
14 0 1 0 0 0
15 0 0 1 0 0
2) 或使用 apply
f2 <- function(data, cols) transform(data, min = apply(data[cols], 1, min))
f2(Data, c("C1", "C2", "C4"))
3) 或 Reduce
f3 <- function(data, cols) transform(data, min = Reduce(pmin, data[cols]))
f3(Data, c("C1", "C2", "C4"))
4) 如果 data[cols] 只有 0 和 1 个单元格,那么如果我们计算一行中 0 的数量,那么如果总和为 0,则最小值应该为 1否则最小值为 0。请注意,当强制转换为逻辑值时,0 被视为 FALSE,任何其他数字都被视为 TRUE:
f4 <- function(data, cols) transform(data, min = +!rowSums(!data[cols]))
f4(Data, c("C1", "C2", "C4"))
我们可以使用 tidyverse
包中的一些函数快速完成此操作。这里的关键是不使用引号,将列包裹在vars
中,然后在函数中使用三重爆炸!!!
分隔和计算。
library(tidyverse)
min.col <- function(data, conditions){
data %>%
mutate(Min = pmin(!!!conditions))
}
min.col(Data, vars(C1, C2))
#> C1 C2 C3 C4 Min
#> 1 1 0 0 0 0
#> 2 0 1 1 0 0
#> 3 1 1 0 0 1
#> 4 1 1 0 1 1
#> 5 0 0 0 0 0
#> 6 0 1 0 0 0
#> 7 1 0 1 0 0
#> 8 1 0 1 1 0
#> 9 0 0 1 0 0
#> 10 0 1 0 0 0
#> 11 0 1 1 0 0
#> 12 1 1 1 1 1
#> 13 1 0 0 0 0
#> 14 0 1 0 0 0
#> 15 0 0 1 0 0