R Dplyr:将缺失的行添加到整数列的间隙中
R Dplyr: Adding Missing Rows into Gaps in a Column of Integers
我正在使用 R 中的 dplyr 包来“总结”一些输入数据。
第 1 步: 计算给定日期 (Date) 的记录数 (N),除了另一个分类值外,还具有特定索引值 (Idx) A 列
T <- orig_data %>% group_by(A, Date, Idx) %>% summarise(N=n())
第 2 步:创建给定日期具有给定 Idx 值或更高值的计数的累计总和。
T2 <- T %>% mutate(cN=cumsum(N))
但是,table 中不存在一些介于最大值和最小值之间的 Idx 值,例如下面的示例中缺少 Idx=10。
A Date Idx N cN
N 2020-10-01 8 18 85
N 2020-10-01 9 6 91
N 2020-10-01 11 1 92
N 2020-10-01 13 10 102
我想在缺失的每一天为每个缺失的 Idx 值添加一行,例如
N 2020-10-01 10 0 91
我尝试使用最简单的填充函数版本来尝试此操作,但结果没有产生明显的变化(可能是因为 Idx 被解释为列表而不是向量?)
T3 <- T2 %>% fill(cN)
有没有办法轻松添加上面的行,并找出任何其他缺失的行并将它们添加到 table?
我找到的最佳解决方案(我之前 运行 遇到过同样的问题)是创建一个替代数据框,其中包括我关心的完整序列。然后,我将我真正的主要数据集加入到那个替身中。
有点hacky,但只需几行就可以完成。它还会产生感兴趣的结果。
library(dplyr)
df <- data.frame(idx = c(8, 9, 11, 12), n = c(11, 22, 33, 44)) %>%
left_join(
x = data.frame(idx = seq(min(.$idx), max(.$idx))),
y = .)
df
输出:
idx n
1 8 11
2 9 22
3 10 NA
4 11 33
5 12 44
使用 tidyr
函数的解决方案:complete
和 nesting
。我看到你在另一个post评论说你试过complete
功能,但是很慢。尝试 nesting
列以查看是否有帮助。
library(dplyr)
library(tidyr)
dat2 <- dat %>%
complete(nesting(A, Date), Idx = full_seq(Idx, period = 1), fill = list(N = 0)) %>%
fill(cN)
dat2
# # A tibble: 6 x 5
# A Date Idx N cN
# <chr> <chr> <dbl> <dbl> <int>
# 1 N 2020-10-01 8 18 85
# 2 N 2020-10-01 9 6 91
# 3 N 2020-10-01 10 0 91
# 4 N 2020-10-01 11 1 92
# 5 N 2020-10-01 12 0 92
# 6 N 2020-10-01 13 10 102
我正在使用 R 中的 dplyr 包来“总结”一些输入数据。
第 1 步: 计算给定日期 (Date) 的记录数 (N),除了另一个分类值外,还具有特定索引值 (Idx) A 列
T <- orig_data %>% group_by(A, Date, Idx) %>% summarise(N=n())
第 2 步:创建给定日期具有给定 Idx 值或更高值的计数的累计总和。
T2 <- T %>% mutate(cN=cumsum(N))
但是,table 中不存在一些介于最大值和最小值之间的 Idx 值,例如下面的示例中缺少 Idx=10。
A Date Idx N cN
N 2020-10-01 8 18 85
N 2020-10-01 9 6 91
N 2020-10-01 11 1 92
N 2020-10-01 13 10 102
我想在缺失的每一天为每个缺失的 Idx 值添加一行,例如
N 2020-10-01 10 0 91
我尝试使用最简单的填充函数版本来尝试此操作,但结果没有产生明显的变化(可能是因为 Idx 被解释为列表而不是向量?)
T3 <- T2 %>% fill(cN)
有没有办法轻松添加上面的行,并找出任何其他缺失的行并将它们添加到 table?
我找到的最佳解决方案(我之前 运行 遇到过同样的问题)是创建一个替代数据框,其中包括我关心的完整序列。然后,我将我真正的主要数据集加入到那个替身中。
有点hacky,但只需几行就可以完成。它还会产生感兴趣的结果。
library(dplyr)
df <- data.frame(idx = c(8, 9, 11, 12), n = c(11, 22, 33, 44)) %>%
left_join(
x = data.frame(idx = seq(min(.$idx), max(.$idx))),
y = .)
df
输出:
idx n
1 8 11
2 9 22
3 10 NA
4 11 33
5 12 44
使用 tidyr
函数的解决方案:complete
和 nesting
。我看到你在另一个post评论说你试过complete
功能,但是很慢。尝试 nesting
列以查看是否有帮助。
library(dplyr)
library(tidyr)
dat2 <- dat %>%
complete(nesting(A, Date), Idx = full_seq(Idx, period = 1), fill = list(N = 0)) %>%
fill(cN)
dat2
# # A tibble: 6 x 5
# A Date Idx N cN
# <chr> <chr> <dbl> <dbl> <int>
# 1 N 2020-10-01 8 18 85
# 2 N 2020-10-01 9 6 91
# 3 N 2020-10-01 10 0 91
# 4 N 2020-10-01 11 1 92
# 5 N 2020-10-01 12 0 92
# 6 N 2020-10-01 13 10 102