2016-08-11 9 views
0

Ich habe einen Datenrahmen mit verschiedenen Arten von Strings. Ich möchte die Strings in sich selbst duplizieren, und behalten Sie den NA-Wert und zwei Ziffernfolgen bleiben NA und zwei Ziffern.R add strings in Datenrahmen

DF: 
    Milk  Cola Juice Coffee Tea Wine 
1 A  NA  A  BD  C A 
2 AB  NA  C  D  CD AD 
3 A  BC  AC  D  D D 
4 AB  B  NA  D  CD AD 
5 B  C  AC  BD  CD NA 
6 AB  BC  C  NA  NA A 
7 NA  BC  A  B  NA A 

Desired output: 
    Milk  Cola Juice Coffee Tea Wine 
1 AA  NA  AA  BD  CC AA 
2 AB  NA  CC  DD  CD AD 
3 AA  BC  AC  DD  DD DD 
4 AB  BB  NA  DD  CD AD 
5 BB  CC  AC  BD  CD NA 
6 AB  BC  CC  NA  NA AA 
7 NA  BC  AA  BB  NA AA 

Vielen Dank.

Antwort

4

Hier ist ein Versuch, einen regulären Ausdruck Wechsel mit:

dat[] <- lapply(dat, function(x) sub("^(.)$", paste(rep("\\1",2),collapse=""), x)) 

oder weniger programmatisch, aber mit dem gleichen Ergebnis:

dat[] <- lapply(dat, function(x) sub("^(.)$", "\\1\\1", x)) 

Oder wenn Sie wirklich zum Squash-Code gehen, dann:

dat[] <- lapply(dat, sub, pa="^(.)$", re="\\1\\1") 

Wo dat war:

structure(list(Milk = c("A", "AB", "A", "AB", "B", "AB", NA), 
    Cola = c(NA, NA, "BC", "B", "C", "BC", "BC"), Juice = c("A", 
    "C", "AC", NA, "AC", "C", "A"), Coffee = c("BD", "D", "D", 
    "D", "BD", NA, "B"), Tea = c("C", "CD", "D", "CD", "CD", 
    NA, NA), Wine = c("A", "AD", "D", "AD", NA, "A", "A")), .Names = c("Milk", 
"Cola", "Juice", "Coffee", "Tea", "Wine"), row.names = c("1", 
"2", "3", "4", "5", "6", "7"), class = "data.frame") 
4
DF <- " Milk  Cola Juice Coffee Tea Wine 
1 A  NA  A  BD  C A 
2 AB  NA  C  D  CD AD 
3 A  BC  AC  D  D D 
4 AB  B  NA  D  CD AD 
5 B  C  AC  BD  CD NA 
6 AB  BC  C  NA  NA A 
7 NA  BC  A  B  NA A " 
DF <- read.table(text=DF, stringsAsFactors=FALSE) 

Dies ist DF:

Milk Cola Juice Coffee Tea Wine 
1 A <NA>  A  BD C A 
2 AB <NA>  C  D CD AD 
3 A BC AC  D D D 
4 AB B <NA>  D CD AD 
5 B C AC  BD CD <NA> 
6 AB BC  C <NA> <NA> A 
7 <NA> BC  A  B <NA> A 

Ihr Ziel zu erreichen, nutzen wir lapply und ifelse machen kann.

DF[] <- lapply(DF, function(x) ifelse(nchar(x) == 1, paste(x, x, sep=""), x)) 

Für jede Spalte, wenn das Zahlenzeichen im Eintrag 1 ist, wir es duplizieren; Ansonsten bewahren Sie es als Original auf.

fertige Ausgabe:

> DF 
    Milk Cola Juice Coffee Tea Wine 
1 AA <NA> AA  BD CC AA 
2 AB <NA> CC  DD CD AD 
3 AA BC AC  DD DD DD 
4 AB BB <NA>  DD CD AD 
5 BB CC AC  BD CD <NA> 
6 AB BC CC <NA> <NA> AA 
7 <NA> BC AA  BB <NA> AA 
2

Wir können dies auch strrep mit tun, die schneller sein sollte, wie es in C

DF[] <- lapply(DF, function(x) ifelse(nchar(x)==1, strrep(x,2), x)) 
DF 
# Milk Cola Juice Coffee Tea Wine 
#1 AA <NA> AA  BD CC AA 
#2 AB <NA> CC  DD CD AD 
#3 AA BC AC  DD DD DD 
#4 AB BB <NA>  DD CD AD 
#5 BB CC AC  BD CD <NA> 
#6 AB BC CC <NA> <NA> AA 
#7 <NA> BC AA  BB <NA> AA 

Eine Option dplyr würde mit geschrieben sein

library(dplyr) 
DF %>% 
    mutate_each(funs(ifelse(nchar(.)==1, strrep(., 2), .)))