【问题标题】:dplyr-how to insert NA values when the column sort order changesdplyr-如何在列排序顺序更改时插入 NA 值
【发布时间】:2015-11-21 10:44:53
【问题描述】:

当列值从increasing 顺序更改为混合顺序时,我试图找出一种插入NA 值的简单方法。但是,如果在这种混合排序的行之后逻辑上继续增加顺序,那么也可以保留这些行。

如果所有行都没有升序,请将这些行值替换为NA。 (表示所有行混合排序)

此外,任何可以在其行内保持排序序列至少 5 个数字的列都可以通过(可以保持其行具有有序部分的行)。否则,替换 NA 值那些无法通过此逻辑的行。

我最好用 dplyr 来完成这个过程。我试图这样做,但无法想出这个主意:(。

dt_new <- dt%>%
    mutate_each(funs(replace(., which(ifelse(.....

示例数据

set.seed(123) 
C1 = c(1:10,7,8,11,12)
C2 = c(2:12,7,13,12)
C3 = sample(1:14)
C4 = c(1:14)
C5 = c(sample(1:9),5,6,7,8,10)

dt <- data.frame(C1,C2,C3,C4,C5)

       C1 C2 C3 C4 C5
#   1   1  2  5  1  1
#   2   2  3 11  2  8
#   3   3  4 14  3  2
#   4   4  5 10  4  9
#   5   5  6 13  5  7
#   6   6  7  1  6  4
#   7   7  8 12  7  3
#   8   8  9  7  8  5
#   9   9 10  4  9  6
#   10 10 11  3 10  5
#   11  7 12  6 11  6
#   12  8  7  2 12  7 
#   13 11 13  2 13  8
#   14 12 12  9 14 10

我要查找的输出

       C1 C2 C3 C4 C5
#   1   1  2 NA  1  1
#   2   2  3 NA  2 NA
#   3   3  4 NA  3  2 
#   4   4  5 NA  4 NA
#   5   5  6 NA  5 NA
#   6   6  7 NA  6 NA
#   7   7  8 NA  7  3
#   8   8  9 NA  8 NA
#   9   9 10 NA  9 NA
#   10 10 11 NA 10 5
#   11 NA 12 NA 11 6
#   12 NA NA NA 12 7
#   13 11 13 NA 13 8
#   14 12 NA NA 14 9

【问题讨论】:

  • 为什么dt$C5[1] 变成NA ?我曾期望 1 留在那里。 (嗯,这不是我唯一不明白的,我通过了)
  • @Tensibai pass 意味着如果至少 5 行可以在该 C5 列显示递增的顺序序列,则可以保留它们。其他行应该是NA
  • 所以你只会保留 5 个连续(增加)行的块?抱歉,您的预期输出很难与输入匹配,而且我不清楚逻辑
  • @Tensibai 如果是这样,如果逻辑顺序发生变化,您至少可以提供一个答案。
  • 您应该修正与您的输入相关的预期输出。据我所知,您的问题 C5 行应该是 c(1,NA,2,NA,NA,NA,3,5,6,NA,NA,7,8,10) 或者 c(1,NA,2, NA,NA,NA,3,NA,NA,5,6,7,8,10) 或者整个 NA 我无法确定到底是哪一个

标签: r sorting if-statement dplyr


【解决方案1】:

这是一个相当牵强的解决方案...它适用于先前的输出,但不适用于当前的 C5:它会删除第一次匹配之前的任何值,使之成为一系列 5 个连续递增的值。

  1. 找出变量中是否存在一系列 5 个递增值。将值与lag 进行比较。使用rle 查找系列 5。
  2. 如果没有serie,则返回length=length(var)的NA向量
  3. 其他
    1. 将每个值与前一个值进行比较,如果较差则删除
    2. 如果先前的值已被删除,则再次传递以与最后一个未删除的值进行比较。如果劣质则删除。在删除值时重复此操作。

代码:

library(dplyr)
library(zoo)

co <- function(var){
  r <- rle(lag(var) < var)
  d <- data.frame(v=r$values,
                  l=r$lengths,
                  c=cumsum(r$lengths))
  idx <- which(d$l > 3 & d$v==TRUE)[1] - 1
  id <- d$c[idx]


  v <- rep(NA,length(var))
  if(!is.na(id)) {
    p <- id:length(v)
    v[p] <- ifelse(var[p] > lag(var[p]),
                              var[p],
                              NA)
    v[id] <- var[id]

    previous.na <- sum(is.na(lag(v[p])))

    if(previous.na > 1) {
      current.na <- 0

      while(current.na != previous.na)
      { 
        previous.na <- sum(is.na(v))
        v[p][is.na(lag(v[p]))][-1] <- ifelse(v[p][is.na(lag(v[p]))][-1] > lag(na.locf(v[p]))[is.na(lag(v[p]))][-1],
                                             v[p][is.na(lag(v[p]))][-1],
                                             NA)
        v[id] <- var[id]
        current.na <- sum(is.na(v))
      }

    }
  }

  print(var)
  return(v)
}
mutate_each(dt,funs = funs(co))

输出

   C1 C2 C3 C4 C5
1   1  2 NA  1 NA
2   2  3 NA  2 NA
3   3  4 NA  3 NA
4   4  5 NA  4 NA
5   5  6 NA  5 NA
6   6  7 NA  6 NA
7   7  8 NA  7 NA
8   8  9 NA  8 NA
9   9 10 NA  9 NA
10 10 11 NA 10  5
11 NA 12 NA 11  6
12 NA NA NA 12  7
13 11 13 NA 13  8
14 12 NA NA 14 10

我使用了这个数据集(对 C5 重复 set.seed)

C1 = c(1:10,7,8,11,12)
C2 = c(2:12,7,13,12)
set.seed(123) 
C3 = sample(1:14)
C4 = c(1:14)
set.seed(456) 
C5 = c(sample(1:9),5,6,7,8,10)
dt <- data.frame(C1,C2,C3,C4,C5)

【讨论】:

  • @scoa 感谢您花费时间和精力编写如此复杂的代码。顺便说一句,你怎么能写出这种我做不到的逻辑流程?你有学习建议书或wep页面吗?
  • @scoa 如果我想将这个co 函数推广到decreasing,那么应该更改哪个部分?
  • 要更改顺序,每次将vlag(v)varlag(var) 进行比较时,您都需要更改比较符号。 var[p] &gt; lag(var[p]) 变成 var[p] &lt; lag(var[p]) 等等。
  • co &lt;- function(var){ r &lt;- rle(lag(var) &lt; var) d &lt;- data.frame(v=r$values, l=r$lengths, c=cumsum(r$lengths)) idx_s &lt;- d$c[which(d$l &gt; 3 &amp; d$v==TRUE)[1] - 1] idx_e &lt;- d$c[which(d$l &gt; 3 &amp; d$v==TRUE)[1]] v &lt;- rep(NA,length(var)) if(!is.na(idx_s)) v[idx_s:idx_e] &lt;- var[idx_s:idx_e] print(var) return(v) }
  • 是的。如果整个语句在一行上,则可以省略括号
猜你喜欢
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
  • 2015-07-04
  • 2022-07-28
  • 1970-01-01
相关资源
最近更新 更多