没有循环的Dataframe中的子字符串,填充和粘贴列

Die*_*lue 9 string r dataframe stringr

我有这个数据框,它看起来像这样:

在此输入图像描述

我需要从列中的第一个字符开始,将整个值放入a中,然后在末尾放置一个计数器,在a列中重复递增.此计数器必须始终为三.最终结果如下:

在此输入图像描述

所以没有什么戏剧性的,我能用以下代码做这件事(准备给人留下深刻的印象):

library(stringr) 
tk <- ""
for (i in 1:nrow(df)){
  if (tk == df$an[i]){
    counter <- counter + 1
  } else {
    tk <- df$an[i]
    counter <- 1
  }
  df$ap[i] <- counter
}

df$ap <- paste0(substr(df$at, 1, 1), df$an, str_pad(df$ap, 3, pad="0"))
Run Code Online (Sandbox Code Playgroud)

我对这次灾难不满意.它似乎不是很"R",我非常希望永远不要让它看到光明的一天.我怎样才能让这更"R"?

我很欣赏这个建议.

CPa*_*Pak 9

library(stringr)
library(dplyr)
df1 <- df %>%
          group_by(an) %>%
          mutate(ap=paste0(substr(at, 1, 1), an, str_pad(row_number(), 3, pad="0")))

     at     an         ap
1   NDA 023356 N023356001
2  ANDA 023357 A023357001
3  ANDA 023357 A023357002
4   NDA 023357 N023357003
5  ANDA 023398 A023398001
Run Code Online (Sandbox Code Playgroud)


Fra*_*ank 8

rleidrowid功能从data.table可能是有用的位置:

# using df from @Florian's answer
library(data.table)
setDT(df)

df[, v := paste0(
  substr(at, 1, 1), 
  an, 
  sprintf("%03.f", rowid(rleid(an)))
)]

#      at     an          v
# 1:  NDA 023356 N023356001
# 2: ANDA 023357 A023357001
# 3: ANDA 023357 A023357002
# 4:  NDA 023357 N023357003
# 5: ANDA 023398 A023398001
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  • sprintf从基地有效地完成stringr::str_padOP 的工作.
  • rleid 组一起运行重复值.
  • rowid 在每个组内制作一个计数器.


lmo*_*lmo 6

在基数R中,您可以使用sprintf填充0和ave来获取如下计数:

df$ap <- paste0(substr(df$at, 1, 1), df$an,
                sprintf("%03.0f", as.numeric(ave(df$an, df$an, FUN=seq_along))))
Run Code Online (Sandbox Code Playgroud)

ave执行组计算并seq_along计算行数.

返回

df
    at     an         ap
1  NDA 023356 N023356001
2 ANDA 023357 A023357001
3 ANDA 023357 A023357002
4  NDA 023357 N023357003
5 ANDA 023398 A023398001
Run Code Online (Sandbox Code Playgroud)