根据另一列中的动态范围确定是否满足条件

时间:2018-01-31 23:59:10

标签: r

我有一个列有很多零值和偶尔的十进制值,例如

c <- c(0,0,0,0.0927,0,0,0.100821,0) 

我有一个单独的列v,其中包含所有十进制数字:

v <- c(0.091,0.0981,0.101,0.102,0.092,0.1,0.091,0.099)

如果c中的值> 0,我想从该观察结果(即从该行向下)查看列v ,看看是否,在该范围内的任何位置,有一个值低于c的行/观察中的特定值。理想情况下,我想返回较低数字的第一个实例的值和/或行号/索引。

输出如下所示: (NA,NA,NA,5,NA,NA,8,NA)

即。输出返回v中下一个实例的v中的行号,该值小于C中的相应数字。它忽略v,.091中的第一个值,即使它低于C(.0927)中的第一个数字,因为它发生在C之前(数据按时间顺序排列)。我只想查看后续行。

我真的非常感谢任何帮助。 :-) w ^

4 个答案:

答案 0 :(得分:1)

假设可以有多个符合条件的值(即v中的多个元素低于c中的正值

positiveMatches <- which(c > 0) #Find the positive values in c

resultList <- list() #Set up a vector to store our data frames

#Loop through each positive match
for(i in positiveMatches){

    elementName <- paste0(i, "_", c[i]) #Name the list element after the index and value in c

    restrictedV <- c(rep(FALSE, i-1), rep(TRUE, length(v)-(i-1)))
    lowerMatches <- (v[i:length(v)] < c[i]) & restrictedV #Find the index of those elements in v which are less than our positive match in c
    resultList[[elementName]] <- data.frame(index = which(lowerMatches),
                                            value = v[lowerMatches]
                                            )
}

这应该给你一个数据帧列表,其中每个元素以c中的索引和值命名,并且数据帧在v中包含每个合适元素1行,提供v中每个元素的索引和值比c中的那个。

enter image description here

这里唯一的技巧是计算我们的值为真的索引。我使用which命令执行此操作以获取c中的索引。一旦我拥有了这些值,我就可以循环遍历它们,并计算出适用于每个c的索引,我用lowerMatches <- v < c[i]做了这个。一旦我获得了所有信息,我就必须将它们绑定到一个数据帧中。

你没有给出你希望输出结果的例子,所以我提出了一些我认为会很好的东西。您可能希望修改此代码以将c的索引和值存储为除列表元素名称之外的其他内容。

您可以使用names(resultList)来获取这些内容,但此时您应该尝试修改代码以将这些值存储在更有用的位置。

编辑:我意识到我错过了“从这一点向下”部分,所以我在restrictedV中添加了一个额外的检查,它只生成一个允许的所有值的索引。如果您不希望它包含与c中相同的行(即忽略索引5),只需将i-1更改为i检查中的restrictedV

答案 1 :(得分:1)

我不完全确定逻辑,但这会重现您的预期结果并且很短(仅限基础R)。

sapply(seq_along(c), function(i) {
    idx <- which(v < c[i]);
    if (length(idx) > 0) return(min(idx[idx > i])) else return(NA);
})
#[1] NA NA NA  5 NA NA  8 NA

样本数据

c <- c(0,0,0,0.0927,0,0,0.100821,0)
v <- c(0.091,0.0981,0.101,0.102,0.092,0.1,0.091,0.099)

答案 2 :(得分:0)

我认为这可以满足您的需求吗?此方法定义要应用于数据的每一行的自定义函数,然后使用purrr::pmap将函数应用于每一行并生成一个向量。然后,您可以将矢量绑定为数据的新列。这避免了for循环,但这是否值得,这是值得怀疑的。如果NA不为正,则结果为c的新列;如果小于v则为最低的行索引;如果不是{&1},则为0 39;吨

您给出的示例没有可能出现的两种情况。每次c为正数时,v大于后来的值,因此0永远不会返回此处。此外,v中可以有相同的值,这使得&#34;的索引定义为最小值&#34;暧昧。这也可能是一种更简单的方法。

编辑:我看到示例数据已更改,您实际上是在寻找第一个较低的值,而不是最小值。如果你不先修改这个答案,请尝试回到这个并修复它!


library(tidyverse, quietly = TRUE)
v <- c(0.09199,0.0981,0.101,0.10002,0.0927273,0.1,0.091,0.099,0.105,0.1,0.1,0.1,0.1,0.100821,0.09)
c <- c(0,0,0,0,0.0927273,0,0,0,0,0,0,0,0,0.100821,0)

tbl <- tibble(c, v) %>% rowid_to_column()

is_v_lower <- function(rowid, c, v){
  if (c <= 0){
    return(NA)
  } else if (v > min(tbl$v[(rowid + 1):nrow(tbl)])) {
    min_index = which.min(tbl$v[(rowid + 1):nrow(tbl)])
    later_rowid = tbl$rowid[(rowid + 1):nrow(tbl)]
    return(later_rowid[min_index])
  } else {
    return(0)
  }
}

output <- pmap_chr(tbl, is_v_lower)

new_tbl <- bind_cols(tbl, lower_v_index = output) %>% print()
#> # A tibble: 15 x 4
#>    rowid      c      v lower_v_index
#>    <int>  <dbl>  <dbl> <chr>        
#>  1     1 0      0.0920 <NA>         
#>  2     2 0      0.0981 <NA>         
#>  3     3 0      0.101  <NA>         
#>  4     4 0      0.100  <NA>         
#>  5     5 0.0927 0.0927 15           
#>  6     6 0      0.100  <NA>         
#>  7     7 0      0.0910 <NA>         
#>  8     8 0      0.0990 <NA>         
#>  9     9 0      0.105  <NA>         
#> 10    10 0      0.100  <NA>         
#> 11    11 0      0.100  <NA>         
#> 12    12 0      0.100  <NA>         
#> 13    13 0      0.100  <NA>         
#> 14    14 0.101  0.101  15           
#> 15    15 0      0.0900 <NA>

答案 3 :(得分:0)

使用&#34; tidyverse&#34;定义tibbles(data.frames)和%>%运算符(管道;请参阅magrittr包中的?"%>%")。

library(tidyverse)

对于任何组和向量x和y,我认为你的标准是(根据需要进行调整......)

f = function(x, y) { y[1] = x[1]; which.max(y < y[1]) }

使用行索引列i从原始数据创建一个tibble。根据{{​​1}}

的非零值的出现对行进行分组
c

总结tbl,提取每组中的相关信息

tbl = tibble(i = seq_along(c), c, v) %>% group_by(grp = cumsum(c != 0))

将原始表格加入答案并清理

ans = summarize(tbl, i = i[1], idx = i[1] + f(c, v) - 1L)

也许在> left_join(tbl, ans) %>% ungroup() %>% select(-i, -grp) Joining, by = c("i", "grp") # A tibble: 8 x 3 c v idx <dbl> <dbl> <int> 1 0 0.0910 1 2 0 0.0981 NA 3 0 0.101 NA 4 0.0927 0.102 5 5 0 0.0920 NA 6 0 0.100 NA 7 0.101 0.0910 8 8 0 0.0990 NA 中放置更多逻辑,例如

f()

当例如在v中的值不小于c时尝试确定结果时,这将有所帮助。