【问题标题】:Generate new id column based off other ids in different column根据不同列中的其他 id 生成新的 id 列
【发布时间】:2020-10-20 18:28:31
【问题描述】:

这可能看起来有点微不足道,但我正在尝试根据另一列中的 id 生成 id。但是,新的 id 应该基于公式构建,并且应该为第一列中的每个 id 递增 1:5

所以是这样的:

list_ids_2 <- tibble(id = rep(c(12345, 34564, 234521, 90889), each = 5))

# For each id in `list_ids_2` there should be 5 ids 
# with this formula (100*(id + 1200) + j), 
# where j starts at 1 and increases until 5 
# at which point it moves to the next id and does the #same thing again.

#This works only in the sense that it produces 20 new ids. Ideally though, the initial ids #(above) wouldn't already have to be replicated 5 times.

list_ids_2$new_id <- 0

for (i in unique(list_ids_2$id)) {
  #print(i)
  
  for (j in 1:5){
    
    #print(j)
    
    b <- (( 100 * (i + 1200) + j))
    
    print(b)
    
    #list_ids_2$new_id[1,1] <- b
  }
}

[1] 124234501
[1] 124234502
[1] 124234503
[1] 124234504
[1] 124234505
[1] 126456401
[1] 126456402
[1] 126456403
[1] 126456404
[1] 126456405
[1] 146452101
[1] 146452102
[1] 146452103
[1] 146452104
[1] 146452105
[1] 132088901
[1] 132088902
[1] 132088903
[1] 132088904
[1] 132088905
#Adding this to the list_ids_2 tibble doesn't work though.

这也适用,但不会增加数字1:5

generator <- function(x){
  
  j <-  1
  
  while(j <= 5){
    
    b <- (( 100 * (x + 1200) + j))
    
    j <-  j + 1
    
    return(b)
    print(b)
    
  }
  
}

generator(c(1234,1234))
[1] 123123401 123123401

理想情况下,我会从一个数据框开始,可能必须以一个新的数据框/tibble b/c 维度结束,这就是为什么不能将结果添加到 list_ids_2 tibble .

非常感谢任何帮助!

【问题讨论】:

  • 你能给出一个期望输出的样本吗?

标签: r


【解决方案1】:

您可以将outersapply+ 一起使用:

id = c(12345, 34564, 234521, 90889)

outer(id, 1:5, "+")
#        [,1]   [,2]   [,3]   [,4]   [,5]
# [1,]  12346  12347  12348  12349  12350
# [2,]  34565  34566  34567  34568  34569
# [3,] 234522 234523 234524 234525 234526
# [4,]  90890  90891  90892  90893  90894

sapply(id, "+", 1:5)
#       [,1]  [,2]   [,3]  [,4]
# [1,] 12346 34565 234522 90890
# [2,] 12347 34566 234523 90891
# [3,] 12348 34567 234524 90892
# [4,] 12349 34568 234525 90893
# [5,] 12350 34569 234526 90894

在这两种情况下,您都会得到 matrix 结果。在其上使用c()as.vector() 将其变成正则向量。

在任何一种情况下,您都可以使用100 * (id + 1200) 作为第一个输入,而不是未转换的id

将这些部分放在一起:

c(sapply(100 * (id + 1200), "+", 1:5))
#  [1]  1354501  1354502  1354503  1354504  1354505  3576401
#  [7]  3576402  3576403  3576404  3576405 23572101 23572102
# [13] 23572103 23572104 23572105  9208901  9208902  9208903
# [19]  9208904  9208905

这里有一对tidyverse 改编:

# starting with repeated IDs
list_ids_2 %>%
  group_by(id) %>%
  mutate(idx = 100 * (id + 1200) + row_number())


# starting with unique IDs
uid = unique(list_ids_2)
uid %>%
  mutate(idx = map(100 * (id + 1200), ~ . + 1:5)) %>%
  unnest(idx)

【讨论】:

  • 非常感谢!我会试一试。你知道这是否也适用于 tidyverse 设置中的map
  • 当然,map(id, ~ . + 1:5) 也可以工作,尽管它会返回 list()
  • 添加了几个快速 tidyverse 方法
  • 太棒了!非常感谢!
【解决方案2】:

使用 purrr map2() 可能如下所示。

library(dplyr)
library(purrr)

list_ids_2 %>%
  group_by(id) %>%
  mutate(j = 1:n()) %>%
  ungroup() %>%
  mutate(idx = unlist(map2(id, j,  ~ 100*(.x + 1200) + .y))) %>%
  select(-j)

#       id      idx
#    <dbl>    <dbl>
# 1  12345  1354501
# 2  12345  1354502
# 3  12345  1354503
# 4  12345  1354504
# 5  12345  1354505
# 6  34564  3576401
# 7  34564  3576402
# 8  34564  3576403
# 9  34564  3576404
# 10 34564  3576405

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多