将多组参数应用于用户定义的函数
sapply with multiple set of arguments to an user defined function
我有一个数据框 df
并且想使用函数 range_frac
来执行操作。
set.seed(137)
df <- data.frame(col1 = sample(LETTERS, 100, TRUE),
col2 = sample(-75:75, 100, TRUE),
col3 = sample(-75:75, 100, TRUE))
df$col2[c(23, 48, 78)] <- NA
df$col3[c(37, 68, 81)] <- NA
range_frac <- function(n, my_df, my_var) {
len = sum(my_df[my_var] < n, na.rm = TRUE)
len
}
我想分别知道满足col2
和col3
条件的行数。由于我传递列名不成功,所以我传递了列索引(2
,3
)。但是,当我尝试为 my_var
传递向量时,它会汇总各个值的输出。这是怎么发生的?
sapply(1:3, range_frac, my_df = df, my_var = 2)
[1] 57 57 57
sapply(1:3, range_frac, my_df = df, my_var = 3)
[1] 51 51 52
sapply(1:3, range_frac, my_df = df, my_var = 2:3)
[1] 108 108 109
有人可以解释第三次操作的结果(即 57+51、57+51、57+52)吗?
(基本上,我试图以 dyplr
-summarise
的方式实现以下输出,但停留在这一点上,我想我会清楚我对这个概念的理解)。
n col2 col3
1 57 51
2 57 51
3 57 52
更新: 我问了一个不清楚的问题,所以用更多信息更新它。解决方法如下:
对于每个 n
解决方案可以理解为表达式的评估
sum(df[,2:3] < n, na.rm = TRUE)
而不是单独用于列 2
&3
.
我们以下面的代码为例
sapply(1:3, range_frac, my_df = df, my_var = 2:3)
这里,1:3
作为第一个参数传递给range_frac
,相当于迭代,例如
for (i in 1:3) {
range_frac(...)
}
在sapply
中,my_df = df
和my_var = 2:3
作为传递给range_frac
的第二个和第三个参数。因此,整个 sapply
行可以解释为
res <- c()
for (i in 1:3) {
res[i] <- range_frac(i, df, 2:3)
}
一些解决方法
sapply(1:3,Vectorize(range_frac,"my_var"),my_df = df, my_var = 2:3)
sapply(1:3,function(k) sapply(2:3,function(v) range_frac(k,df,v)))
如果输入2:3
到my_var
,range_frac()
实际执行
sum(df[2:3] < n, na.rm = TRUE)
每个 n
。当然你在第二列和第三列中得到小于 n
的元素数。一种解决方案是将参数 my_var
向量化,即
sapply(1:3, Vectorize(range_frac, "my_var"), my_df = df, my_var = 2:3)
# [,1] [,2] [,3]
# [1,] 48 48 48
# [2,] 49 51 51
我有一个数据框 df
并且想使用函数 range_frac
来执行操作。
set.seed(137)
df <- data.frame(col1 = sample(LETTERS, 100, TRUE),
col2 = sample(-75:75, 100, TRUE),
col3 = sample(-75:75, 100, TRUE))
df$col2[c(23, 48, 78)] <- NA
df$col3[c(37, 68, 81)] <- NA
range_frac <- function(n, my_df, my_var) {
len = sum(my_df[my_var] < n, na.rm = TRUE)
len
}
我想分别知道满足col2
和col3
条件的行数。由于我传递列名不成功,所以我传递了列索引(2
,3
)。但是,当我尝试为 my_var
传递向量时,它会汇总各个值的输出。这是怎么发生的?
sapply(1:3, range_frac, my_df = df, my_var = 2)
[1] 57 57 57
sapply(1:3, range_frac, my_df = df, my_var = 3)
[1] 51 51 52
sapply(1:3, range_frac, my_df = df, my_var = 2:3)
[1] 108 108 109
有人可以解释第三次操作的结果(即 57+51、57+51、57+52)吗?
(基本上,我试图以 dyplr
-summarise
的方式实现以下输出,但停留在这一点上,我想我会清楚我对这个概念的理解)。
n col2 col3
1 57 51
2 57 51
3 57 52
更新: 我问了一个不清楚的问题,所以用更多信息更新它。解决方法如下:
对于每个 n
解决方案可以理解为表达式的评估
sum(df[,2:3] < n, na.rm = TRUE)
而不是单独用于列 2
&3
.
我们以下面的代码为例
sapply(1:3, range_frac, my_df = df, my_var = 2:3)
这里,1:3
作为第一个参数传递给range_frac
,相当于迭代,例如
for (i in 1:3) {
range_frac(...)
}
在sapply
中,my_df = df
和my_var = 2:3
作为传递给range_frac
的第二个和第三个参数。因此,整个 sapply
行可以解释为
res <- c()
for (i in 1:3) {
res[i] <- range_frac(i, df, 2:3)
}
一些解决方法
sapply(1:3,Vectorize(range_frac,"my_var"),my_df = df, my_var = 2:3)
sapply(1:3,function(k) sapply(2:3,function(v) range_frac(k,df,v)))
如果输入2:3
到my_var
,range_frac()
实际执行
sum(df[2:3] < n, na.rm = TRUE)
每个 n
。当然你在第二列和第三列中得到小于 n
的元素数。一种解决方案是将参数 my_var
向量化,即
sapply(1:3, Vectorize(range_frac, "my_var"), my_df = df, my_var = 2:3)
# [,1] [,2] [,3]
# [1,] 48 48 48
# [2,] 49 51 51