首页 > 解决方案 > 使用 apply 在函数中添加条件

问题描述

我想编写一个条件函数来应用于我的数据框。

现有的功能是:

Proposed <- function(N_b,N_l,m,A,x.sqr,e_1,e_2,e_3,e_4,e_5,K_g,a,b,c,d) {
  e <- data.frame(e_1,e_2,e_3,e_4,e_5,N_l)
  ee <- e[e != 0]
  CSi <- m * ((N_l/N_b) * ((a*K_g)^b) + 
            ((A * apply(ee,1,function(v) max(combn(v[1:ncol(ee)],v["N_l"],sum))))
              / x.sqr) * ((c*K_g)^d))
  return(CSi)
}

条件有两个方面:

我想添加条件 if A > 0then select max(combn(v[1:5],v["N_l"],sum))。但是如果A < 0选择min(combn(v[1:5],v["N_l"],sum))

数据

提供了一个示例数据框(只有几行)

dput(DATA)
structure(list(N_l = c(2, 4, 2, 4, 1, 2, 1, 3), N_b = c(5, 5, 
5, 5, 5, 5, 5, 5), m = c(1, 0.65, 1, 0.65, 1.2, 1, 1.2, 0.85), 
A = c(-12, -12, -15, -15, -9, -9, -9, -9), x.sqr = c(1440, 
1440, 2250, 2250, 810, 810, 810, 810), e_1 = c(21.8, 21.8, 
29, 29, 14.6, 14.6, 14.6, 14.6), e_2 = c(9.8, 9.8, 17, 17, 
2.6, 2.6, 2.6, 2.6), e_3 = c(-2.2, -2.2, 5, 5, -9.4, -9.4, 
-9.4, -9.4), e_4 = c(-14.2, -14.2, -7, -7, 0, 0, 0, 0), e_5 = c(0, 
0, -19, -19, 0, 0, 0, 0), K_g = c(6340598.65753794, 6340598.65753794, 
6429472.98493414, 6429472.98493414, 6296482.86883766, 6296482.86883766, 
8140521.8248051, 8140521.8248051)), row.names = c(20L, 40L, 
60L, 80L, 100L, 120L, 140L, 160L), class = "data.frame")

标签: rfunctiondataframeconditional-statements

解决方案


max(combn(v, n, sum))与 相同sum(tail(v,n)),没有combn必要。例如,

v <- 1:5
n <- 3
combn(v, n, sum)
#  [1]  6  7  8  8  9 10  9 10 11 12
sum(tail(sort(v), n))
# [1] 12

同样,min(combn(...))只是最小的两个之和。有了这个,你的combn电话可以被简化。

一个简单的功能:

func2 <- function(x) { # A=x[1], N_l=x[2], e_*=x[-(1:2)]
  decr <- (x[1] > 0)
  sum(head(sort(x[-(1:2)], decreasing = decr), x[2]))
}

为了“有趣的数据”,我将A在每一行中否定:

dat$A
# [1] -12 -12 -15 -15  -9  -9  -9  -9
dat$A[c(2,4,6,8)] <- (-dat$A[c(2,4,6,8)])
dat$A
# [1] -12  12 -15  15  -9   9  -9   9

它的用途:

apply(dat[,c("A", "N_l", grep("^e_", colnames(dat), value = TRUE))],
      1, func2)
#    20    40    60    80   100   120   140   160 
# -16.4  29.4 -26.0  44.0  -9.4  17.2  -9.4  17.2 

(如果您愿意,可以将其分配给框架中的新变量。)

分解:让我们调试它并运行第一行:

debug(func2)
# debugging in: FUN(newX[, i], ...)
# debug at #1: {
#     decr <- (x[1] > 0)
#     sum(head(sort(x[-(1:2)], decreasing = decr), x[2]))
# }
# Browse[2]> 
x
#     A   N_l   e_1   e_2   e_3   e_4   e_5 
# -12.0   2.0  21.8   9.8  -2.2 -14.2   0.0 

我们的x变量包含了一切,所以我们需要单独引用它们。我们可以使用x["A"]而不是x[1],这样会更清晰易读。交给你。

# Browse[2]> 
decr <- (x[1] > 0)
# Browse[2]> 
decr
#     A 
# FALSE 
# Browse[2]> 
sort(x[-(1:2)], decreasing = decr)
#   e_4   e_3   e_5   e_2   e_1 
# -14.2  -2.2   0.0   9.8  21.8 

好的,所以在这一行中,A小于 0,所以我们想要N_l(2) 个最低值,所以当我们对它们进行排序时,最低值在前。

# Browse[2]> 
head(sort(x[-(1:2)], decreasing = decr), x[2])
#   e_4   e_3 
# -14.2  -2.2 
# Browse[2]> 
sum(head(sort(x[-(1:2)], decreasing = decr), x[2]))
# [1] -16.4

我们将重复第二行,在那里我改为A正数(现在N_l是 4):

# debugging in: FUN(newX[, i], ...)
# debug at #1: {
#     decr <- (x[1] > 0)
#     sum(head(sort(x[-(1:2)], decreasing = decr), x[2]))
# }
x
#     A   N_l   e_1   e_2   e_3   e_4   e_5 
#  12.0   4.0  21.8   9.8  -2.2 -14.2   0.0 
decr <- (x[1] > 0)
decr
#    A 
# TRUE 
sort(x[-(1:2)], decreasing = decr)
#   e_1   e_2   e_5   e_3   e_4 
#  21.8   9.8   0.0  -2.2 -14.2 
head(sort(x[-(1:2)], decreasing = decr), x[2])
#  e_1  e_2  e_5  e_3 
# 21.8  9.8  0.0 -2.2 
sum(head(sort(x[-(1:2)], decreasing = decr), x[2]))
# [1] 29.4

重复他们所有。(如果您在控制台上执行此操作,请重新加载/重新定义函数,或调用undebug(func2).


推荐阅读