【问题标题】:How do I find the 1st non-NA value in a row?如何连续找到第一个非 NA 值?
【发布时间】:2020-02-24 21:42:57
【问题描述】:

假设我有以下内容:

df <- data.frame(dt=c(as.Date('2019-02-02'), as.Date('2019-02-04'), as.Date('2019-02-05'), as.Date('2020-03-04')), v1=c(1,2,NA,NA), v2=c(NA,3,4,NA), v3=c(NA,NA,3,5), v4=c(2, 4, 6, NA))
> read.zoo(df)
           v1 v2 v3 v4
2019-02-02  1 NA NA  2
2019-02-04  2  3 NA  4
2019-02-05 NA  4  3  6
2020-03-04 NA NA  5 NA

我想在每行中找到第一个非 NA 值,该值出现在具有值的列之后。

例如,对于'2019-02-02':

  • v1 中有一个值为 1,v2 有 NA,所以我们跳过,v3 有 NA,所以我们跳过,但 v4 不是 NA,所以我想返回它的值,第 1 行为 2,第 1 列。
  • 查看下一列v2,在同一行中它是 NA,所以我们跳过它,因为它不是数字
  • v3 也是 NA 所以我们跳过它。
  • v4 不是 NA,但它后面没有列,所以我们返回 NA。

因此我们的第一行将是:

c1 c2 c3 c4
2  NA NA NA

遍历此示例中的所有行,我期望输出为:

             c1 c2 c3 c4
1 2019-02-02  2 NA NA NA
2 2019-02-04  3  4 NA NA
3 2019-02-05 NA  3  6 NA
4 2020-03-04 NA NA NA NA

看起来我需要做的就是将每行中的列值向左移动,但我似乎不知道该怎么做......

注意:我更喜欢使用 zoo 的 base-R 解决方案

【问题讨论】:

  • 看来v1 没关系——这样对吗?
  • 这很重要,因为如果v1 是 NA,那么 c1 在该行中将是 NA(因为我们跳过了 NA)。如果v1 不是NA,那么c1 可能具有来自v1 右侧某个列的值(如果v1 右侧的某个列不是NA)
  • 啊,“将每行中的列值向左移动”的描述是有道理的。
  • :-) 解释这个问题有点难,但这让我很吃惊……

标签: r dataframe zoo


【解决方案1】:

这是一个应用自定义函数的解决方案:

res = t(apply(df[-1], 1, function(x) {
     val = which(!is.na(x))
     x[val[-length(val)]] = x[val[-1]]
     x[val[length(val)]] = NA
     return(x)
     }
  ))

cbind(df[1], res)
#           dt v1 v2 v3 v4
# 1 2019-02-02  2 NA NA NA
# 2 2019-02-04  3  4 NA NA
# 3 2019-02-05 NA  3  6 NA
# 4 2020-03-04 NA NA NA NA

【讨论】:

  • 这很聪明。需要考虑一下 :-) 如果您有一个简短的解释为什么会起作用,那么对于将来看到这个的人肯定会有所帮助......
  • 啊,我知道你是怎么做到的了。谢谢!
【解决方案2】:

我不知道如何使用base R。但在tidyverse

df %>% 
gather(key, value, -dt) %>% 
arrange(dt, key) %>% 
mutate(key2 = as.numeric(substr(key, 2, 2))) %>% 
filter(!is.na(value)) %>% group_by(dt) %>% 
mutate(ind = lag(key2, default = NA), index = paste0("c", ind)) %>% 
ungroup() %>% 
filter(!is.na(ind)) %>% 
select(dt, index, value) %>% 
spread(index, value)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 2018-04-12
    • 2011-10-12
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多