在 R 中的每个实体的最小行要求条件下插入具有 NA 值的行数
inserting numbers of rows with NA value with the condition of minimum row requirement for each entity in R
我有一个数据框如下。我想为每个 ID
设置一个最小行变量(让我们称之为 min_row
),这意味着每个 ID
应该至少有 min_row
条记录。如果没有,我想为该 ID
插入一行,另一列为 NA
值(这里是 subject
列)。
min_row_id=3
df
ID subject
1 A1
1 A2
2 A1
3 A1
3 A2
3 A3
3 A4
resutl:
ID subject
1 A1
1 A2
1 NA
2 A1
2 NA
2 NA
3 A1
3 A2
3 A3
3 A4
所以每个ID
至少有3条记录。
我怎样才能在 R 中做到这一点?谢谢
一种只使用基数 R 的方法是
#Get number of rows for each ID and subtract it from min_row_id
#keep only those which we need to add
temp <- subset(aggregate(subject~ID, df, function(x) min_row_id - length(x)),
subject < min_row_id & subject > 0)
#Add those new rows and rbind the original dataframe
new_df <- rbind(df, do.call(rbind, mapply(function(x, y)
data.frame(ID = x, subject = rep(NA, y)),
temp$ID, temp$subject, SIMPLIFY = FALSE)))
#If needed order them according to ID
new_df[order(new_df$ID), ]
# ID subject
#1 1 A1
#2 1 A2
#8 1 <NA>
#3 2 A1
#9 2 <NA>
#10 2 <NA>
#4 3 A1
#5 3 A2
#6 3 A3
#7 3 A4
这是使用 tidyr::complete
的一种方法。我们创建了一个 record_number
列来计算每个 ID
组的记录。然后 complete
将让我们填写所有缺失的行,因此每个组的记录数与记录数最多的组一样多(或者如果没有组有 3 条记录,则最多填充 3 行)。然后我们过滤掉每组添加的超过 3 行的无关行。
library(tidyverse)
tbl <- read_table2(
"ID subject
1 A1
1 A2
2 A1
3 A1
3 A2
3 A3
3 A4"
)
tbl %>%
group_by(ID) %>%
mutate(record_number = row_number()) %>%
ungroup() %>%
complete(ID, record_number = 1:max(3, max(record_number))) %>%
filter(record_number <=3 | !is.na(subject))
#> # A tibble: 10 x 3
#> ID record_number subject
#> <dbl> <int> <chr>
#> 1 1 1 A1
#> 2 1 2 A2
#> 3 1 3 <NA>
#> 4 2 1 A1
#> 5 2 2 <NA>
#> 6 2 3 <NA>
#> 7 3 1 A1
#> 8 3 2 A2
#> 9 3 3 A3
#> 10 3 4 A4
由 reprex package (v0.2.1)
于 2019-02-06 创建
另一个base
备选方案。使用 tapply
在每个 'ID' 中索引 ([
) 'subject',从组 length
的 1 到 max
和 3 (min_row_id).对于超过组长的索引,对应的值为NA
.
通过rep
将列表元素的名称与每个元素的长度关联起来 (lengths
),重新创建正确长度的 'ID'。使用 unlist
创建一个 'subject' 列。
l <- tapply(d$subject, d$ID, function(x) x[1:(max(c(length(x), 3)))])
data.frame(id = rep(names(l), lengths(l)), subject = unlist(l, use.names = FALSE))
# id subject
# 1 1 A1
# 2 1 A2
# 3 1 <NA>
# 4 2 A1
# 5 2 <NA>
# 6 2 <NA>
# 7 3 A1
# 8 3 A2
# 9 3 A3
# 10 3 A4
我有一个数据框如下。我想为每个 ID
设置一个最小行变量(让我们称之为 min_row
),这意味着每个 ID
应该至少有 min_row
条记录。如果没有,我想为该 ID
插入一行,另一列为 NA
值(这里是 subject
列)。
min_row_id=3
df
ID subject
1 A1
1 A2
2 A1
3 A1
3 A2
3 A3
3 A4
resutl:
ID subject
1 A1
1 A2
1 NA
2 A1
2 NA
2 NA
3 A1
3 A2
3 A3
3 A4
所以每个ID
至少有3条记录。
我怎样才能在 R 中做到这一点?谢谢
一种只使用基数 R 的方法是
#Get number of rows for each ID and subtract it from min_row_id
#keep only those which we need to add
temp <- subset(aggregate(subject~ID, df, function(x) min_row_id - length(x)),
subject < min_row_id & subject > 0)
#Add those new rows and rbind the original dataframe
new_df <- rbind(df, do.call(rbind, mapply(function(x, y)
data.frame(ID = x, subject = rep(NA, y)),
temp$ID, temp$subject, SIMPLIFY = FALSE)))
#If needed order them according to ID
new_df[order(new_df$ID), ]
# ID subject
#1 1 A1
#2 1 A2
#8 1 <NA>
#3 2 A1
#9 2 <NA>
#10 2 <NA>
#4 3 A1
#5 3 A2
#6 3 A3
#7 3 A4
这是使用 tidyr::complete
的一种方法。我们创建了一个 record_number
列来计算每个 ID
组的记录。然后 complete
将让我们填写所有缺失的行,因此每个组的记录数与记录数最多的组一样多(或者如果没有组有 3 条记录,则最多填充 3 行)。然后我们过滤掉每组添加的超过 3 行的无关行。
library(tidyverse)
tbl <- read_table2(
"ID subject
1 A1
1 A2
2 A1
3 A1
3 A2
3 A3
3 A4"
)
tbl %>%
group_by(ID) %>%
mutate(record_number = row_number()) %>%
ungroup() %>%
complete(ID, record_number = 1:max(3, max(record_number))) %>%
filter(record_number <=3 | !is.na(subject))
#> # A tibble: 10 x 3
#> ID record_number subject
#> <dbl> <int> <chr>
#> 1 1 1 A1
#> 2 1 2 A2
#> 3 1 3 <NA>
#> 4 2 1 A1
#> 5 2 2 <NA>
#> 6 2 3 <NA>
#> 7 3 1 A1
#> 8 3 2 A2
#> 9 3 3 A3
#> 10 3 4 A4
由 reprex package (v0.2.1)
于 2019-02-06 创建另一个base
备选方案。使用 tapply
在每个 'ID' 中索引 ([
) 'subject',从组 length
的 1 到 max
和 3 (min_row_id).对于超过组长的索引,对应的值为NA
.
通过rep
将列表元素的名称与每个元素的长度关联起来 (lengths
),重新创建正确长度的 'ID'。使用 unlist
创建一个 'subject' 列。
l <- tapply(d$subject, d$ID, function(x) x[1:(max(c(length(x), 3)))])
data.frame(id = rep(names(l), lengths(l)), subject = unlist(l, use.names = FALSE))
# id subject
# 1 1 A1
# 2 1 A2
# 3 1 <NA>
# 4 2 A1
# 5 2 <NA>
# 6 2 <NA>
# 7 3 A1
# 8 3 A2
# 9 3 A3
# 10 3 A4