2017-07-21 11 views
8

Tôi có dataframe này, nó trông như thế này:xâu, Pad và Paste Cột trong Dataframe mà không có một vòng

enter image description here

tôi cần phải thực hiện ký tự đầu tiên từ cột tại, toàn bộ giá trị trong một , sau đó đặt một bộ đếm ở đầu để tăng số lần lặp lại trong cột a. Bộ đếm này phải luôn có độ dài là ba. Kết quả cuối cùng là thế này:

enter image description here

Vì vậy, không có gì ở đây mà ấn tượng, tôi đã có thể làm điều này với đoạn mã sau (chuẩn bị được ấn tượng):

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")) 

Tôi rất không hài lòng với sự thất bại này. Nó có vẻ không phải là rất "R" và tôi muốn rất nhiều không bao giờ để cho phép điều này để xem ánh sáng trong ngày. Làm thế nào tôi có thể làm cho điều này "R" hơn?

Tôi đánh giá cao lời khuyên.

+1

Bạn có thể đăng đầu ra 'dput (DF)' cho ví dụ năm hàng không? – Frank

+1

Tất cả những câu trả lời này đều rất hữu ích trong việc giúp tôi hiểu r tốt hơn. Tôi sẽ học các kỹ thuật cho từng cái này. Nhưng ai nhận được 'câu trả lời' thèm muốn? Tôi có xu hướng chỉ cần đi với những upvotes nhất bởi vì tất cả họ đều tuyệt vời ... và dplyr thắng. – DieselBlue

Trả lời

8
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 
3

này hoạt động:

library(stringr)  
df = data.frame(at=c("NDA","ANDA","ANDA","NDA","ANDA"),an=c("023356","023357","023357","023357","023398"),stringsAsFactors = F) 

df$ap = paste0(substr(df$at,1,1), 
       df$an,str_pad(ave(df$an, df$an, FUN = seq_along),width=3,pad="0")) 

Output:

at  an   ap 
1 NDA 023356 N023356001 
2 ANDA 023357 A023357001 
3 ANDA 023357 A023357002 
4 NDA 023357 N023357003 
5 ANDA 023398 A023398001 

Hope this helps!

+0

Giải pháp này thực sự đã giải quyết được một vấn đề khác mà tôi có! cảm ơn @Florian! – DieselBlue

+0

Tuyệt vời, vui vì tôi có thể giúp! – Florian

6

Trong cơ sở R, bạn có thể sử dụng sprintf để 0s pad và ave để có được số lượng như thế này:

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

ave thực hiện các tính toán nhóm và seq_along đếm các hàng.

trả về

df 
    at  an   ap 
1 NDA 023356 N023356001 
2 ANDA 023357 A023357001 
3 ANDA 023357 A023357002 
4 NDA 023357 N023357003 
5 ANDA 023398 A023398001 
+0

OP đề cập đến "một bộ đếm ở cuối mà gia số lặp lại trong cột" và cũng có các nhóm bằng cách lặp lại với vòng lặp của chúng, nhưng cách tiếp cận của bạn chỉ hoạt động với các giá trị để nhóm, không lặp lại các giá trị. Có lẽ dữ liệu của họ được sắp xếp và những gì tôi nói ở đây không thực sự quan trọng đối với họ. – Frank

+1

@Frank Cảm ơn những người đứng đầu. Tôi đã không nhận được sự phức tạp thêm vào lần đọc đầu tiên của bài viết và nó không phải là trong ví dụ, nhưng tôi sẽ có một cái nhìn thứ hai vào cuối tuần này. – lmo

8

Các rleidrowid chức năng từ data.table có thể hữu ích ở đây:

# 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 

Cách hoạt động:

  • sprintf từ cơ sở một cách hiệu quả Làm công việc của stringr::str_pad trong OP.
  • rleid nhóm chạy các giá trị lặp lại với nhau.
  • rowid đặt bộ đếm trong mỗi nhóm.
Các vấn đề liên quan