【问题标题】:Find the difference of a column ignoring NAs. Find difference only of numbers查找忽略 NA 的列的差异。仅查找数字的差异
【发布时间】:2021-07-23 09:22:44
【问题描述】:

如果我有一个这样的数据集,并且想要找到每个具有 NA 的列的差异,保持 NA 并找到现有数字之间的差异。

x   y
NA  8
NA  21
5   NA
7   NA
NA  NA
0   NA
NA  30
13  8
13  NA
NA  3

期望的输出是

x   y
NA  NA
NA  13
NA  NA
2   NA
NA  NA
-7  NA
NA  9
13  -22
0  NA
NA  -5

【问题讨论】:

    标签: r dataframe diff


    【解决方案1】:

    也许不是最好的方法,但我认为这可以为你解决问题:

    my_df <- data.frame(x = c(NA, NA, 5, 7, NA, 0, NA, 13, 13, NA),
                        y = c(8, 21, NA, NA, NA, NA, 30, 8, NA, 3),
                        stringsAsFactors = FALSE)
    
    my_var <- which(!is.na(my_df$y))
    if (length(my_var)) {
      my_a <- my_df[my_var, "y"]
      my_a <- my_a[-length(my_var)]
      my_b <- my_df[my_var, "y"]
      my_b <- my_b[-1]
      my_c <- my_b - my_a
      my_var <- my_var[-1]
      my_df[my_var, "Diff"] <- my_c
    }
    

    【讨论】:

      【解决方案2】:

      使用data.tablezoo

      df <- data.table(df)
      
      df[, x := ifelse(!is.na(x), c(NA, diff(na.locf0(x))), NA)]
      df[, y := ifelse(!is.na(y), c(NA, diff(na.locf0(y))), NA)]
      

      编辑:优雅地在一行中:

      df <- data.table(df)
      
      df[, c("x", "y") := lapply(.SD, function(x) ifelse(!is.na(x), c(NA, diff(na.locf0(x))), NA))]
      

      【讨论】:

      • 我可以使用循环对每个 x,y 执行此操作吗?
      • 已编辑,使用 lapply 而不是循环。
      【解决方案3】:

      您可以编写一个函数来计算连续非 NA 值之间的差异并将它们适当地放置。

      calculate_diff <- function(x) {
        x[which(!is.na(x))] <- c(NA, diff(na.omit(x)))
        x
      }
      

      这个函数可以使用lapply应用于base R中的所有列-

      df[] <- lapply(df, calculate_diff)
      df
      
      #    x   y
      #1  NA  NA
      #2  NA  13
      #3  NA  NA
      #4   2  NA
      #5  NA  NA
      #6  -7  NA
      #7  NA   9
      #8  13 -22
      #9   0  NA
      #10 NA  -5
      

      或者在dplyracross -

      library(dplyr)
      df <- df %>% mutate(across(.fns = calculate_diff))
      

      【讨论】:

        猜你喜欢
        • 2021-11-22
        • 2017-11-13
        • 1970-01-01
        • 2011-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多