计入连续的非NA项目

问题描述 投票:0回答:1

我有一个数据集,看起来像这样。

library(purrr)
library(dplyr) 
temp<-as.data.frame(cbind(col_A<-c(1,2,NA,3,4,5,6),col_B<-c(NA,1,2,NA,1,NA,NA)))
names(temp)<-c("col_A","col_B")
col_A      col_B
 1         NA           
 2         1           
 NA        2
 3         NA
 4         3
 5         NA
 6         NA

我想创建一个新的数据框架 它包含了每一列的非NA项目的数量 就像下面的例子一样

count_A      count_B
 1           0           
 2           1           
 0           2
 1           0
 2           1
 3           0
 4           0

我很难得到项目的数量。我最接近的近似值是这样的。

count_days<-function(prev,new){
ifelse(!is.na(new),prev+1,0)
}

temp[,"col_A"] %>% 
mutate(count_a=accumulate(count_a,count_days))

但是我得到了以下的错误。

Error in UseMethod("mutate_") : 
   no applicable method for 'mutate_' applied to an object of class "c('double', 'numeric')"

有谁能帮我解决这段代码或者再给我看一眼。

我知道这段代码只是尝试计数,而不是创建新的df,我认为在我得到正确的结果后,这更容易。

r dplyr purrr
1个回答
3
投票

使用 rle 嵌套 lapply 办法。我们首先 list 如果数据中的某个元素 is.na. 然后,使用 rle 我们对数值和长度进行解码。那些长度是 NA 我们设定 0 乘法 unlist 的东西。

res <- as.data.frame(lapply(lapply(temp, is.na), function(x) {
  r <- rle(x)
  s <- sapply(r$lengths, seq)
  s[r$values] <- lapply(s[r$values], `*`, 0)
  unlist(s)
}))
res
#   col_A col_B
# 1     1     0
# 2     2     1
# 3     0     2
# 4     1     0
# 5     2     1
# 6     3     0
# 7     4     0

1
投票

我们可以用 rleiddata.table

library(data.table)
setDT(temp)[, lapply(.SD, function(x) rowid(rleid(!is.na(x))) * !is.na(x))]
#    col_A col_B
#1:     1     0
#2:     2     1
#3:     0     2
#4:     1     0
#5:     2     1
#6:     3     0
#7:     4     0

0
投票
library(tidyverse)

您可以使用 sequencerledata.table首先将所有非NA设为1,然后 rle 连号

library(data.table)

temp %>% 
  replace(.,!is.na(.),1) %>% 
  mutate(col_A=case_when(!is.na(col_A)~sequence(rle(col_A)$lengths))) %>% 
  mutate(col_B=case_when(!is.na(col_B)~sequence(rle(col_B)$lengths))) %>% 
  replace(.,is.na(.),0)
© www.soinside.com 2019 - 2024. All rights reserved.