【问题标题】:Add a condition within the function with apply使用 apply 在函数中添加条件
【发布时间】:2021-01-28 00:56:13
【问题描述】:

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

现有的功能是:

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)
}

条件有两个方面:

我想添加条件,如果A &gt; 0 然后选择max(combn(v[1:5],v["N_l"],sum))。但是如果A &lt; 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")

【问题讨论】:

  • 为什么要创建data.frame?如果您的值都是数字,那么 matrix 会快得多,并且您的第二行 e[e != 0] 创建一个向量,它是您的框架的列优先未列出的向量。正因为如此,ee 没有维度,所以apply(ee, 1, ...) 没有意义(应该是Error)。您可能需要提供示例数据和预期输出才能帮助解决此问题。
  • 这对我来说似乎很简单。您是否尝试过使用 if 语句?如果是这样,为什么它不起作用?
  • @r2evans 对于某些行,某些 E_1、E_2 等列的项为零。我不想在combn 函数的考虑中包含does。我只去了一个data.frame,因为这是我在combn 使用示例中看到的示例。
  • @r2evans 我上传了一个示例数据框
  • @LucasDeAbreuMaia 我遇到了一个错误,我认为 r2evans 指的是这个错误。使用 nls 应用它的错误是 Error in apply(ee, 1, function(v) min(combn(v[1:ncol(ee)], v["N_l"], sum))) : dim( X) 必须具有正长度

标签: r function dataframe conditional-statements


【解决方案1】:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-06
    • 2023-03-08
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    相关资源
    最近更新 更多