2017-07-21 122 views
8

Bu dataframe var, şuna benzer:Alt dize bir döngü olmadan Dataframe içinde Pad ve Yapıştır Sütunlar

enter image description here

Ben de kolondan ilk karakteri almak için bütün değer gerekir daha sonra, sütun a'daki tekrarlar için artışlar yapan bir sayaç koyun. Bu sayaç her zaman üç uzunluğunda olmalı.

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

Öyle değilim:

Yani hiçbir şey burada o dramatik, Aşağıdaki kod ile bunu başardı

enter image description here

(hazırlamak Etkilenmem): Nihai sonuç şudur Bu debacle memnun. Çok "R" gibi görünmüyor ve bu günün ışığını görmesine izin vermemeyi çok isterim. Bunu daha "R" nasıl yapabilirim?

Tavsiyeyi takdir ediyorum.

+1

Beş satırlı örnek için "dput (DF)" çıkışını kaydeder misiniz? – Frank

+1

Tüm bu cevaplar, doğruyu daha iyi anlamamda bana yardımcı oluyor. Bunların her biri için teknikleri öğreneceğim. Ama kime 'cevap' kim alır? Ben sadece en upvotes ile gitmek için eğimliyim çünkü hepsi harika ve dplyr kazanır. – DieselBlue

cevap

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

Bu çalışır:

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

Çıktı: Bu yardımcı olur

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

Umut!

+0

Bu çözüm aslında sahip olduğum farklı bir sorunu çözdü! teşekkürler @Florian! – DieselBlue

+0

Harika, yardımcı olabildiğime sevindim! – Florian

6

baz Ar, sen böyle sayımlarını almak için ped 0 ve ave sprintf kullanabilirsiniz:

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

ave grup hesaplamaları ve seq_along sayımları satırlar gerçekleştirir. data.table gelen

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, "bir sütunda tekrarlar için artışlar içeren bir sayaçtan" ​​ve aynı zamanda döngüleri ile tekrarlayan gruplardan bahseder, ancak yaklaşımınız yalnızca değerlerin tekrarlanmaması için gruplandırma değerleri ile çalışır. Muhtemelen onların verileri sıralanır ve burada söylediğim şey aslında onlar için önemli değildir. – Frank

+1

@Frank Başlıklar için teşekkürler. Eklemenin ilk okunmasında ek karmaşıklık elde etmedim ve bu örnekte değil, ama bu haftasonuna ikinci bir göz atacağım. – lmo

8

rleid ve rowid işlevlerini döndürür

burada yararlı olabilir:

# 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 

Nasıl çalışır: etkin bir tabanından

  • sprintf iş yapar mı OP'de stringr::str_pad. rleid grupları tekrar eden değerleri birlikte çalıştırır. Her grupta bir sayaç yapar.
  • rowid.