我有一个数据集,看起来像这样。
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,我认为在我得到正确的结果后,这更容易。
使用 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
我们可以用 rleid
从 data.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
library(tidyverse)
您可以使用 sequence
和 rle
从 data.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)