我想创建一个可以模拟 n 次的函数。我的最终目标是找出每 n 次模拟的 c 总和。我是 R 编码的初学者,所以我刚刚开始练习 for 循环和 if else 语句。
这就是我现在希望实现的目标:如果 a> b,c 将为“2”,如果 a < b,c 将为“-2”。如果a=b,则c将由下一行的a和b值确定。这是我到目前为止所拥有的,但我不断收到错误。我想知道 a=b 是否是我应该如何处理这个问题。如有任何帮助,我们将不胜感激。
a<-c(5,6,7,8,9,10,1,4,6,7)
b<-c(4,6,8,5,3,4,5,2,1,3)
c<-c(0,0,0,0,0,0,0,0,0,0)
df<-data.frame(a,b,c)
if(df$a > df$b){
df$c<- c(2)}
else if(df$a < df$b){
df$c<- c(-2)}
else if(df$a == df$b){ # a=b
if(df$a[+1,] > df$b[+1,]) {
df$c<- c(2)}
else(df$a[+1,] < df$b[+1,]){
df$c<- c(-2) }
}
else
print("error")
}
sum(df$c)
最佳答案
问题
if()
和else()
R 中的意思是控制流,并且不是矢量化的。用简单的英语来说,这意味着 if()
期待一个评估为 one 的语句 TRUE
或FALSE
。当你这样做时df$a > df$b
您会得到一个与数据框中的行长度相同的 bool 向量。发生这种情况时,if()
只会使用第一项,并给你一个警告。这会给你错误的答案。
更好的解决方案
我认为您正在寻找ifelse()
这是矢量化的。由于您已经嵌套了 if-else 语句,您最好使用 dplyr::case_when()
.
下面是一个示例,它还修复了 a == b
的情况对于多行:
# Note that I've added two consecutive rows where a == b
a <- c(5,6,6,7,8,9,10,1,4,6,7)
b <- c(4,6,6,8,5,3,4,5,2,1,3)
df <- data.frame(a, b)
library(dplyr)
df %>%
mutate(
c = case_when(
a > b ~ 2,
a < b ~ -2,
# If not a > b nor a < b is TRUE, they must be equal,
# so we set all other cases to NA...
TRUE ~ NA_real_
)
) %>%
# ... and then we use fill() to replace NAs with the first
# non NA valua after it
tidyr::fill(c, .direction = "up")
#> a b c
#> 1 5 4 2
#> 2 6 6 -2
#> 3 6 6 -2
#> 4 7 8 -2
#> 5 8 5 2
#> 6 9 3 2
#> 7 10 4 2
#> 8 1 5 -2
#> 9 4 2 2
#> 10 6 1 2
#> 11 7 3 2
由 reprex package 于 2022 年 3 月 30 日创建(v2.0.1)
这是如何工作的:
-
ifelse()
工作原理类似于if()
和else()
在您的代码中,但它接受多个值 -
case_when()
行为类似于嵌套ifelse()
语句,因此它首先检查是否a > b
并将这些值设置为等于2
,接下来它将检查剩余的行,如果a < b
并将它们设置为-2
等等。 - 如果 a 不小于也不大于 b,则它们必须相等。我们将这些情况设置为
NA
. - 我们使用
tidyr::fill()
之后将缺失值替换为其后的第一个非缺失值实例。这处理有多个连续行a == b
的情况.
关于R 函数求给定列值的 c 之和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71672402/