【问题标题】:For each non-missing element of first vector, compare with lagging elements of second vector对于第一个向量的每个非缺失元素,与第二个向量的滞后元素进行比较
【发布时间】:2020-12-25 06:21:51
【问题描述】:

我确信我的解决方案(请参阅“预期结果”)使问题变得过于复杂。我有两个向量 - 向量 1 用于开始,向量 2 用于测量结束。 NA 表示未记录任何更改。

我想检查奇怪的数据条目 - 即,结束但尚未开始的事情。我只想要合理的数据条目。一个小节可以在下一个小节开始的同时结束(例如,参见示例中的小节“C”)。

我的方法: 我正在使用 cumsum 为起始向量中的每个新的非缺失元素创建切割,并为每个切割检查是否有多个“结束”条目,并在有非 NA 条目时删除 NA。 这个想法是获得一个具有唯一结束值或 NA 的向量,我可以将其与起始向量的唯一元素进行比较。生成的逻辑向量用于子集起始列表。

其他可能相关的信息: 这两个向量实际上是数据框的列。欢迎任何包裹。

另外,如果您有更好的问题标题建议,我很乐意听到。干杯。

start_r <- c("A", NA, NA, "B", NA, NA, "C", NA, NA, "D", NA, "D")
end_r   <- c(NA, "A", NA, NA, "B", "C", NA, NA, NA, "C", NA, NA)

## as suggested by Henrik, here as data frame. 
## "B" has two following entries in column "end_r" and is therefore not plausible
data.frame(start_r, end_r)
#>    start_r end_r
#> 1        A  <NA>
#> 2     <NA>     A
#> 3     <NA>  <NA>
#> 4        B  <NA>
#> 5     <NA>     B
#> 6     <NA>     C
#> 7        C  <NA>
#> 8     <NA>  <NA>
#> 9     <NA>  <NA>
#> 10       D     C
#> 11    <NA>  <NA>
#> 12       D  <NA>

end_lag <- dplyr::lead(end_r)
cs1 <- cumsum(!is.na(start_r))

ls_start <- split(start_r, cs1)

ls_end_lagged <- split(end_lag, cs1)
ls_end_nona <- lapply(ls_end_lagged, 
                        function(x) if(all(is.na(unique(x)))) NA 
                                      else if (length(unique(x[!is.na(x)])) >1) NA
                                        else x[!is.na(x)]
                      )

v_start <- sapply(split(start_r, cs1), function(x) x[!is.na(x)])
v2 <- sapply(ls_end_nona, function(x) x[1])

## desired result
data.frame(start_r = unname(unlist(ls_start[v_start %in% v2])))
#>   start_r
#> 1       A
#> 2    <NA>
#> 3    <NA>
#> 4       C
#> 5    <NA>
#> 6    <NA>

【问题讨论】:

  • 值 B 有什么问题?
  • @arg0naut91 双“结束”条目
  • @Henrik 感谢您的建议。我将发布数据框。 B 不正确,因为下面的“end”有两个条目。所以有一个“C”,要么是错误的输入,要么是“C”没有在“开始”中输入。

标签: r


【解决方案1】:

“v1”也可以用

创建
v1 <- tapply(start_r, cs1, na.omit)

另外一种情况

library(dplyr)
v2 <- stack(ls_end_lagged) %>%
      group_by(ind) %>%
      summarise(values = 
    if(all(is.na(values))| n_distinct(na.omit(values)) > 1 ) NA else 
       first(na.omit(values)) ) %>% 
    pull(values)

-检查输出

unlist(ls_start[v1 %in% v2], use.names = FALSE)
#[1] "A" NA  NA  "C" NA  NA 

或者另一种选择是使用tidyverse 来完成这一切

library(dplyr)
library(tibble)
tibble(start = start_r, end = lead(end_r)) %>%
    group_by(grp = cumsum(!is.na(start))) %>%
    summarise(across(everything(), ~
        if(all(is.na(.)) | n_distinct(na.omit(.)) > 1) NA_character_ 
         else first(na.omit(.))), .groups = 'drop') %>%
    select(-grp)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 2020-07-03
    • 1970-01-01
    相关资源
    最近更新 更多