Han*_*Dup 11 loops for-loop r vector while-loop
我正在寻找一个函数,它接受一个向量并不断删除第一个值,直到向量的总和小于20.返回剩余的值.
我已经尝试了for-loop和while循环,但无法找到解决方案.
vec <- c(3,5,3,4,3,9,1,8,2,5)
short <- function(vec){
for (i in 1:length(vec)){
while (!is.na((sum(vec)) < 20)){
vec <- vec[i+1:length(vec)]
#vec.remove(i)
}
}
Run Code Online (Sandbox Code Playgroud)
预期输出应为:
1,8,2,5
小于20.
Ron*_*hah 12
查看预期输出,看起来您想要删除值,直到剩余值的总和小于20.
我们可以创建一个函数
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Run Code Online (Sandbox Code Playgroud)
尝试另一个输入
drop_20(1:10)
#[1] 9 10
Run Code Online (Sandbox Code Playgroud)
打破功能,首先是 vec
vec = c(3,5,3,4,3,9,1,8,2,5)
Run Code Online (Sandbox Code Playgroud)
然后我们rev解决它
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
Run Code Online (Sandbox Code Playgroud)
取累积总和(cumsum)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Run Code Online (Sandbox Code Playgroud)
找出少于20的企业数量
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
Run Code Online (Sandbox Code Playgroud)
最后用这些最后的进入子集tail.
稍微修改代码,它也应该能够处理NAs
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
Run Code Online (Sandbox Code Playgroud)
逻辑是我们replace NA用零然后接受cumsum
你需要每次删除第一个值,所以你的while循环应该是,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
Run Code Online (Sandbox Code Playgroud)
没有循环的基本解决方案
不是我最可读的代码,但速度非常快(参见下面的基准测试)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
Run Code Online (Sandbox Code Playgroud)
注意:'借用' NA来自@ Ronak的答案
样本数据
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
基准
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
992 次 |
| 最近记录: |