【问题标题】:Calculating column differences while handling NA's在处理 NA 时计算列差异
【发布时间】:2020-07-30 20:24:34
【问题描述】:

我对 R 还很陌生,遇到了一个有趣的问题。我的数据集有很多 NA,处理它们变得有点问题。

我有什么:

  S1 S2 S3 S4
  NA NA 3  4
  1  3  NA NA
  3  NA 5  NA

我想要做的:计算 Diff = S4 - S3 - S2 - S1。但是如果 S4 是 NA,那么它应该做 Diff = S3 - S2 - S1。依此类推……但如果假设 S4 和 S2 是 NA,那么 Diff 应该是 S3 - S1。

例如在第 2 行,答案应该是 2。(3-1)

我需要什么:

 S1 S2 S3 S4 Diff
 NA NA 3  4  1
 1  3  NA NA 2
 3  NA 5  NA 2

到目前为止我所写的:(但不适用于处理 NA)

data <- cbind(data, Diff = data$S4 - data$S3 -data$S2 -data$S1) 

附加信息:原始问题中每列下的值是时间戳。

数据是什么样子的:

head(select(data,S4,S3,S2,S1))

  S4                  S3                  S2                  S1                    
1 2020-07-08 07:46:36 NA                  2020-07-08 07:08:31 NA                 
2 2020-07-08 07:11:57 NA                  2020-07-08 07:08:53 NA                 
3 2020-07-08 07:12:50 NA                  2020-07-08 07:09:40 NA                 
4 2020-07-08 07:13:14 NA                  2020-07-08 07:09:42 NA                 
5 2020-07-08 07:13:46 NA                  2020-07-08 07:10:36 NA                 
6 2020-07-08 07:44:45 NA                  2020-07-08 07:11:42 NA

数据集的更新版本: (包含数据集的最准确表示 - 时间戳转换为秒。)我需要什么? “差异”列。

  S4  S3  S2  S1 Diff                    
1 NA  30  40  NA 10                
1 NA  30  NA  40 10                
1 10  30  40  50 40                
1 30  NA  40  NA 10                
1 10  30  40  NA 30                
1 NA  30  40  50 20       

在这里找到答案:Take difference between first and last observations in a row, where each row is different

【问题讨论】:

    标签: r


    【解决方案1】:

    这是通过apply 提供的基本 R 选项

    df$Diff <- apply(df,1,function(x) 2*tail(na.omit(x),1)-sum(x,na.rm = TRUE))
    

    df$Diff <- apply(df,1,function(x) Reduce("-",rev(na.omit(x))))
    

    这样

    > df
      S1 S2 S3 S4 Diff
    1 NA NA  3  4    1
    2  1  3 NA NA    2
    3  3 NA  5 NA    2
    

    数据

    > dput(df)
    structure(list(S1 = c(NA, 1L, 3L), S2 = c(NA, 3L, NA), S3 = c(3L, 
    NA, 5L), S4 = c(4L, NA, NA)), class = "data.frame", row.names = c(NA, 
    -3L))
    

    编辑

    当有时间戳值时,也许你可以试试下面的代码

    df$Diff <- apply(df,1,function(x) Reduce("-",as.POSIXlt(rev(na.omit(x)))))
    

    这样

    > df
      S1                  S2 S3                  S4      Diff
    1 NA 2020-07-08 07:08:31 NA 2020-07-08 07:46:36 38.083333
    2 NA 2020-07-08 07:08:53 NA 2020-07-08 07:11:57  3.066667
    3 NA 2020-07-08 07:09:40 NA 2020-07-08 07:12:50  3.166667
    4 NA 2020-07-08 07:09:42 NA 2020-07-08 07:13:14  3.533333
    5 NA 2020-07-08 07:10:36 NA 2020-07-08 07:13:46  3.166667
    6 NA 2020-07-08 07:11:42 NA 2020-07-08 07:44:45 33.050000
    

    数据

    > dput(df)
    structure(list(S1 = c(NA, NA, NA, NA, NA, NA), S2 = c("2020-07-08 07:08:31",
    "2020-07-08 07:08:53", "2020-07-08 07:09:40", "2020-07-08 07:09:42",
    "2020-07-08 07:10:36", "2020-07-08 07:11:42"), S3 = c(NA, NA, 
    NA, NA, NA, NA), S4 = c("2020-07-08 07:46:36", "2020-07-08 07:11:57",
    "2020-07-08 07:12:50", "2020-07-08 07:13:14", "2020-07-08 07:13:46",
    "2020-07-08 07:44:45")), row.names = c("1", "2", "3", "4", "5",
    "6"), class = "data.frame")
    

    【讨论】:

    • 嗨,托马斯。虽然这是一个优雅的解决方案,但您能告诉我如何编辑它以允许时间戳信息。上面的问题是原始问题的简化版本。列的值是时间戳,它不允许 2*tail() 操作。
    • @SyedAhmed 你能用一个带时间戳值的小例子吗?否则很难跟踪会发生什么样的错误。
    • @SyedAhmed 不用担心。如果您有三个值,例如S4S3S1,您将有S4-S3 之间的间隔,但您不能使用间隔减去另一个时间戳,因为前者是相对的,而后者是绝对的
    • @SyedAhmed 不,我不认为这是一个编程问题。从物理角度看,用相对时间间隔减去一个时间点是没有意义的
    • @SyedAhmed 看来你已经找到答案了:)
    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 2014-09-17
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 2011-09-23
    • 1970-01-01
    相关资源
    最近更新 更多