【问题标题】:How to add first 'n' elements to a dataframe based on number of rows per group in dplyr如何根据 dplyr 中每组的行数将前“n”个元素添加到数据框中
【发布时间】:2026-02-02 19:20:03
【问题描述】:

我有一个 sparklyr 数据框 df,看起来像这样:

`id  label1   label2  label3  output
 1    car      1       dev     40
 1    jeep     1       test    50
 2    car      2       dev     40
 3    suv      1       dev     50
 3    suv      2       dev     60
 3    suv      2       dev     75
 3    suv      2       dev     70

我还有一个固定长度的向量

vector = c(1,4,3,7)

我想添加一个新列 vector_valdf,具体取决于每个 id, label1, label2 and label3 的行数,以便向量中的第一个 n 值填充为 vector_val 其中 n = 数量每组的行数

我试过了:

df <- (df %>% arrange(id) %>% group_by(id, label1, label2, label3) %>% mutate(n_records=n()) %>% mutate(vector_val = rep(vector, length=n_records)))

这会返回一个错误:

eval_bare(call, env) 中的错误:找不到对象“n_records”

预期输出是:

`id  label1   label2  label3  output vector_val
 1    car      1       dev     40     1
 1    jeep     1       test    50     1
 2    car      2       dev     40     1
 3    suv      1       dev     50     1 
 3    suv      2       dev     60     1
 3    suv      2       dev     75     4
 3    suv      2       dev     70     3

【问题讨论】:

  • 请分享预期输出
  • 为什么最后 3 个值是 1、4 和 3,而它们的 id、label1、label2 和 label3 完全相同?
  • 因为我们在该组中有 3 行。最后 3 行只有 1 个唯一的 id、label1、label2 和 label3 组合。所以这个唯一组合的行数是 3。因为它是 3,所以我需要将向量的前 3 个数字添加到新列 vector_val 中。向量的前 3 个数字是 1、4 和 3。

标签: r dplyr sparklyr


【解决方案1】:
df = read.table(text = "
id  label1   label2  label3  output
1    car      1       dev     40
1    jeep     1       test    50
2    car      2       dev     40
3    suv      1       dev     50
3    suv      2       dev     60
3    suv      2       dev     75
3    suv      2       dev     70
", header=T)

library(tidyverse)

vector = c(1,4,3,7)

df %>%
  group_by(id, label1, label2, label3) %>%           # for each combination
  summarise(n_records = n(),                         # count number of records
            output = list(output)) %>%               # keep output values in a list
  mutate(vector_val = list(vector[1:n_records])) %>% # use number of records to get corresponding vector elements and store them in a list
  unnest() %>%                                       # unnest columns
  ungroup() %>%                                      # forget the grouping
  select(-n_records)                                 # remove column


# # A tibble: 7 x 6
#      id label1 label2 label3 output vector_val
#   <int> <fct>   <int> <fct>   <int>      <dbl>
# 1     1 car         1 dev        40          1
# 2     1 jeep        1 test       50          1
# 3     2 car         2 dev        40          1
# 4     3 suv         1 dev        50          1
# 5     3 suv         2 dev        60          1
# 6     3 suv         2 dev        75          4
# 7     3 suv         2 dev        70          3

【讨论】:

  • 我收到一条错误消息“eval_bare(call, env) 中的错误:找不到对象‘n_records’”
  • 我假设您成功运行了上述解决方案,但是在运行整个数据集时出现错误?哪条线产生了这个错误? mutate?
  • 是的,上面的代码运行良好。但我看到我的 data.frame 不是 R data.frame,而是一个 sparklyr tbl。如果我将 sparklyr tbl 转换为 R data.frame,则此代码可以正常工作。但不适用于 sparklyr 表。
  • 哦,好的!这就说得通了。进行这种转换需要时间吗?您对使用此代码感到满意吗?
  • 我希望sparklyrdplyr 能够顺利工作而不会出现任何问题。这里有一些例子:spark.rstudio.com/dplyr你能把上面这个小数据集转换成一个 sparklyr 表并检查代码是否有效吗?
【解决方案2】:

'tidyverse' 也有一个更短的解决方案,可能更快:

df %>% 
  group_by(id,label1,label2,label3) %>%
  mutate(vector_val=vector[row_number()]) %>%
  ungroup()

# A tibble: 7 x 6
# id label1 label2 label3 output   val
#  <int> <fct>   <int> <fct>   <int> <dbl>
#1     1 car         1 dev        40     1
#2     1 jeep        1 test       50     1
#3     2 car         2 dev        40     1
#4     3 suv         1 dev        50     1
#5     3 suv         2 dev        60     1
#6     3 suv         2 dev        75     4
#7     3 suv         2 dev        70     3

【讨论】: