【问题标题】:r difference between non-NA column valuesr 非 NA 列值之间的差异
【发布时间】:2019-10-02 20:08:20
【问题描述】:

我需要连续计算非 NA 值之间的差异。例如,如果只有a、c和e点有值,而b和d中的值为NA,我需要计算c和a、e和c之间的差值,并留下b和a之间的差值和d 和 c 空白。 d1 是 b 中的非 NA 值与左侧最近的非 NA 值之间的差(必须是 a 中的非 NA 值)。 d2 是 c 中的非 NA 值与左侧最近的非 NA 值之间的差。 d3 是 d 中的非 NA 值与左侧最近的非 NA 值之间的差。 d4 是 e 中的非 NA 值与左侧最近的非 NA 值之间的差。

我认为我缺少一些可在这种情况下使用的 R 函数。我尝试编写一些 ifelse 条件来说明前面的数据点为 NA,结果证明这是一个很长的 ifelse 语句。 df$d1<-ifelse(!is.na(df$a and !is.na(df$b), df$b-df$a) 但是我离 a 越远,ifelse 语句就越复杂。 我也试过写 df$d1<-(!is.na(df$b))-(!is.na(df$a)) 结果不是差异,而是第一个数据点是否为 NA (我在 d1 列中得到 0、1、-1)。

这是我原始数据库的结构:

```a<-c(10, 20, NA, 40, 50, 60)
b<-c(5, NA, 6, 7, NA, 8)
c<-c(NA, 4, 5, NA, 7, 8)
d<-c(NA, 9, 8, 7, 6, 5)
e<-c(3, 4, NA, 5, 6, 7)
df<-data.frame(a, b, c, d, e)```

这就是我需要的结果:

```d1<-c('-5','' ,'' , '-33','', '-52')
d2<-c('', '-16', '-1', '', '-43', '0')
d3<-c('', '5', '3', '0', '-1', '-3')
d4<-c('-2', '-5', '', '-2', '0', '2')
df1<-data.frame(d1, d2, d3, d4)```

【问题讨论】:

    标签: r missing-data


    【解决方案1】:

    这是一个选项。我们使用pmap 遍历行(或使用base R 中的applyMARGIN = 1),获取相邻非NA 元素('i1')的differnce,绑定行(pmap_dfr )、select 列名的正确顺序和rename

    library(dplyr)
    library(stringr)
    library(purrr)
    pmap_dfr(df,  ~ {
           x <- c(...)
          i1 <- !is.na(x)
           diff(x[i1]) %>% 
        as.list}) %>%       
      select(sort(names(.))) %>%
      rename_all(~ str_c('d', seq_along(.)))
    # A tibble: 6 x 4
    #     d1    d2    d3    d4
    #  <dbl> <dbl> <dbl> <dbl>
    #1    -5    NA    NA    -2
    #2    NA   -16     5    -5
    #3    NA    -1     3    NA
    #4   -33    NA     0    -2
    #5    NA   -43    -1     0
    #6   -52     0    -3     2
    

    注意:这里,默认情况下,缺少的元素将用NA 填充。最好不要使用空白字符串 (""),因为它会将列类型从 numeric 更改为 character


    如果我们只有 NA 行,找到

    pmap_dfr(df,  ~ {
         x <- c(...)
        i1 <- !is.na(x)
        if(any(i1)) {
         diff(x[i1]) %>% 
         as.list
        } else set_names(rep(list(NA_real_), length(x)-1), names(x)[-1])}) %>%       
      select(sort(names(.))) %>%
      rename_all(~ str_c('d', seq_along(.)))
    

    【讨论】:

    • @tadat 在这种情况下,只需将数据子集pmap_dfr(select(df, a, b, c, d, e), ~
    • 太棒了,谢谢!这样可行。只有一个问题:假设我在 df 数据框中有其他列,我不包括在差异计算中。如何指定我只想对 a、b、c、d 和 e 列执行此计算?
    • @tadat 我已经提到您可以通过selecting 指定感兴趣的列
    • 谢谢!我还有一个问题:在某些情况下,所有列(a、b、c、d 和 e)都是空白的。目前,这些行只是被省略了。有没有办法在计算差异时保留这些行,只在所有差异列中使用 NA?
    • 你可以有if(all(is.na(x))) NA
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    相关资源
    最近更新 更多