Soru Veri çerçevesindeki sınırlayıcıda sütun ayırma [duplicate]


Bu sorunun zaten bir cevabı var:

Bir ayırıcıya dayanarak veri sütununda bir sütunu ikiye bölmek istiyorum. Örneğin,

a|b
b|c

olmak

a    b
b    c

bir veri çerçevesinde.

Teşekkürler!


76
2017-08-15 18:37


Menşei


İlgili: stackoverflow.com/questions/7033187/sets-in-r-dataframe/... - Chase


Cevaplar:


@Taesung Shin haklı, ama sonra sadece bir kaç büyü yapmak için data.frame. Belirsizlikleri önlemek için "x | y" satırı ekledim:

df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
foo <- data.frame(do.call('rbind', strsplit(as.character(df$FOO),'|',fixed=TRUE)))

Veya, mevcut data.frame'deki sütunları değiştirmek isterseniz:

within(df, FOO<-data.frame(do.call('rbind', strsplit(as.character(FOO), '|', fixed=TRUE))))

Hangi üretir:

  ID FOO.X1 FOO.X2
1 11      a      b
2 12      b      c
3 13      x      y

74
2017-08-15 19:00



100'lü sütunlarla önceden var olan büyük veri çerçevesindeki bir sütunsa ne yapardınız? - Jeff Erickson
iyi soru. Bölmeyi yaparım, bir veri çerçevesine dönüştürürüm, uygun şekilde yeniden adlandırır ( rename işlevinden reshape paket bunu anında yapmak için kullanışlıdır) ve sonra rbind Mevcut veri çerçevesi ile - bir veya daha önceki sütunlar yerine önceki tek sütun yerine yerleştirilmek için ekstra çaba ... - Ben Bolker
Güncellenmiş sürümüm de diğer sütunların birkaç 100'ünü ele alıyor. - Tommy
+1 Bu en genel çözümdür. '|' İle ayrılan farklı sayıdaki değerlerin olduğu durumları bile halledebilir. Tabii ki, bir kişi, daha az elemente sahip olan satırlar için geri dönüşümü olan rbind sonucunu ele almak zorundadır. Ancak diğer çözüm bu durumda başarısız olur. - Yu Shen
Dikkatli ol, length(strsplit('a|', '|', fixed=TRUE)) olduğu 1 -- gibi dokümanlar Diyelim ki: "... ancak dizenin sonunda bir eşleşme varsa, çıktı, eşleşmeyle aynıdır." @YuShen'in dediği gibi, bu çözüm "geri dönüşüm" yapacaktır. Benim için sadece boş alanlar istedim, geri dönüşümü değil. - The Red Pea


Hadley, veri çerçevelerinin içinde bunu yapmak için çok zarif bir çözüm var. reshape paket, işlevi kullanarak colsplit.

require(reshape)
> df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
> df
  ID FOO
1 11 a|b
2 12 b|c
3 13 x|y
> df = transform(df, FOO = colsplit(FOO, split = "\\|", names = c('a', 'b')))
> df
  ID FOO.a FOO.b
1 11     a     b
2 12     b     c
3 13     x     y

52
2017-08-15 19:52



Sonuç olarak, "FOO.a" ve "FOO.b" gibi görünen sütun isimleri olmadan, ancak "a" ve "b" olarak (değiştirmesi kolay, ama sadece merak ediyor ...) bir yol var mı? - Amyunimus
Aşağıdakileri yapabilirsin with(df, cbind(ID, colsplit(df$FOO, pattern = "\\|", names = c('a', 'b')))). Parametrenin olduğunu unutmayın split yeniden adlandırıldı pattern içinde reshape2 hangi sonraki bir sürümü reshape paketi. - Ramnath
Düzenlemem şu anda engelleniyor ... Sadece her atamadan sonra yazdırmak için yanıtınızı güncellerim ... (yeniden)> df <- data.frame (ID = 11: 13, FOO = c ('a | b ',' b | c ',' x | y '))> df ID FOO 1 11 a | b 2 12 b | c 3 13 x | y> df = dönüştürme (df, FOO = colsplit (FOO, bölme = "\\ |", names = c ('a', 'b')))> df ID FOO.a FOO.b 1 11 ab 2 12 bc 3 13 xy - The Red Pea
Ayrıca, sonuçlanacak sütun sayısını bilmiyorsanız, bunu yapmanın bir yolu var mı? - The Red Pea
Bu çözüm ile küçük sorun. Sütunları bir 'iç içe' veri çerçevesine böler, böylece verileri bir çizim için ggplot2sütun adları tanınmıyor. Ben buldum separate işlevi tidyr bu amaç için daha yararlıdır. Cevabı gör @Gregor - Alison Bennett


Yeni popüler tidyr paket bunu yapar separate. Normal ifadeler kullanır, böylece |

df <- data.frame(ID=11:13, FOO=c('a|b', 'b|c', 'x|y'))
separate(data = df, col = FOO, into = c("left", "right"), sep = "\\|")

  ID left right
1 11    a     b
2 12    b     c
3 13    x     y

Bu durumda varsayılanlar, çalışmak için yeterince akıllı olsa da (bölünmemiş alfasayısal karakterleri arar).

separate(data = df, col = FOO, into = c("left", "right"))

45
2018-02-19 17:28



Bu çözüm delice basittir. Teşekkürler!! - Francisco QV


Sadece bu soruyla bağlantılı olarak geldi SO hakkında yeni bir soru.

Bir cevap utanmaz fiş: Kullanımı cSplit "splitstackshape" paketimden:

df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
library(splitstackshape)
cSplit(df, "FOO", "|")
#   ID FOO_1 FOO_2
# 1 11     a     b
# 2 12     b     c
# 3 13     x     y

Bu özel işlev, her bir sütunun farklı bir sınırlayıcısına sahip olsa bile, birden çok sütunun bölünmesini sağlar:

df <- data.frame(ID=11:13, 
                 FOO=c('a|b','b|c','x|y'), 
                 BAR = c("A*B", "B*C", "C*D"))
cSplit(df, c("FOO", "BAR"), c("|", "*"))
#   ID FOO_1 FOO_2 BAR_1 BAR_2
# 1 11     a     b     A     B
# 2 12     b     c     B     C
# 3 13     x     y     C     D

Esasen, kullanmak için bir fantezi kolaylık sarıcı read.table(text = some_character_vector, sep = some_sep) ve bu çıktının orijinaline bağlanması data.frame. Başka bir deyişle, başka Bir baz R yaklaşımı şöyle olabilir:

df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
cbind(df, read.table(text = as.character(df$FOO), sep = "|"))
  ID FOO V1 V2
1 11 a|b  a  b
2 12 b|c  b  c
3 13 x|y  x  y

30
2017-12-05 16:12



Özellikle de, verilerin "içine" girdiği sütun adlarını tanımlamanız gerekmiyor - tospig
Tospig ile katılıyorum. Ben de bu yerli yöntemi seviyorum read.table(c('a|b','c|d'), '|') Eğer yeni bir data.frame oluşturuyorsak, "eğer bir [varolan] veri çerçevesinden" bahsediyor olsak da hile yapabiliriz. - The Red Pea
Read.table'ın olumsuz yanı, sep sadece bir bayt olabilir ve bir hash ayırıcısı yorum olarak yorumlanır mı? read.table(text=c('a#b'), sep='#') sadece bir sütun üretiyor - iki sütun bekledim. - The Red Pea
@TheRedPea, şu anda bir telefonda, ancak yorum karakterini de belirterek istediğiniz sonucu alamıyorsunuz read.table gibi ""? - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto kesinlikle doğru; Bu 2 sütun üretir: read.table(text=c('a#b'), sep='#', comment.char = '') ve tek karakterli sınırlayıcıya gelince, c ('a ~~ b') 'yi gsub'a geçirirsem, ihtiyacım olan tek bayt sınırlayıcıyı alabilirim: gsub('~~','~', c('a~~b')) - The Red Pea


strsplit(c('a|b','b|c'),'|',fixed=TRUE)

6
2017-08-15 18:52





@Ramnath ve @ Tommy'nin cevaplarını birleştirmek, bir veya daha fazla sütun için temel R'de çalışan bir yaklaşım bulmamı sağladı.

Temel kullanım:

> df = data.frame(
+   id=1:3, foo=c('a|b','b|c','c|d'), 
+   bar=c('p|q', 'r|s', 's|t'), stringsAsFactors=F)
> transform(df, test=do.call(rbind, strsplit(foo, '|', fixed=TRUE)), stringsAsFactors=F)
  id foo bar test.1 test.2
1  1 a|b p|q      a      b
2  2 b|c r|s      b      c
3  3 c|d s|t      c      d

Birden çok sütun:

> transform(df, lapply(list(foo,bar),
+ function(x)do.call(rbind, strsplit(x, '|', fixed=TRUE))), stringsAsFactors=F)
  id foo bar X1 X2 X1.1 X2.1
1  1 a|b p|q  a  b    p    q
2  2 b|c r|s  b  c    r    s
3  3 c|d s|t  c  d    s    t

Birden çok bölünmüş sütunun daha iyi adlandırılması:

> transform(df, lapply({l<-list(foo,bar);names(l)=c('foo','bar');l}, 
+                          function(x)do.call(rbind, strsplit(x, '|', fixed=TRUE))), stringsAsFactors=F)
  id foo bar foo.1 foo.2 bar.1 bar.2
1  1 a|b p|q     a     b     p     q
2  2 b|c r|s     b     c     r     s
3  3 c|d s|t     c     d     s     t

4
2018-02-19 17:21