Chciałbym wziąć dane z formularza
before = data.frame(attr = c(1,30,4,6), type=c('foo_and_bar','foo_and_bar_2'))
attr type
1 1 foo_and_bar
2 30 foo_and_bar_2
3 4 foo_and_bar
4 6 foo_and_bar_2
i użyj split()
powyższej kolumny „ type
”, aby uzyskać coś takiego:
attr type_1 type_2
1 1 foo bar
2 30 foo bar_2
3 4 foo bar
4 6 foo bar_2
Wymyśliłem coś niewiarygodnie złożonego z jakąś działającą formą apply
, ale od tego czasu zgubiłem to. Wydawało się to zbyt skomplikowane, aby być najlepszym sposobem. Mogę użyć, strsplit
jak poniżej, ale potem niejasne, jak odzyskać to z powrotem do 2 kolumn w ramce danych.
> strsplit(as.character(before$type),'_and_')
[[1]]
[1] "foo" "bar"
[[2]]
[1] "foo" "bar_2"
[[3]]
[1] "foo" "bar"
[[4]]
[1] "foo" "bar_2"
Dzięki za wszelkie wskazówki. Do tej pory nie zaznajomiłem się z listami R.
left_right <- str_split_fixed(as.character(split_df),'\">',2)
str_split_fixed("aaa...bbb", fixed("..."), 2)
działa dobrze zfixed()
„Dopasuj stały ciąg” wpattern=
argumencie..
oznacza „dowolny znak” w wyrażeniu regularnym.Inną opcją jest użycie nowego pakietu Tidyr.
źródło
str_split_fixed
i dodać kolumny do istniejącej ramki danych)?5 lat później dodano obowiązkowe
data.table
rozwiązanieMożemy również upewnić się, że wynikowe kolumny będą miały poprawne typy i poprawić wydajność poprzez dodawanie
type.convert
ifixed
argumenty (ponieważ"_and_"
tak naprawdę nie jest wyrażeniem regularnym)źródło
'_and_'
wzorców jest różna, możesz sprawdzić maksymalną liczbę dopasowań (tj. przyszłych kolumn) za pomocąmax(lengths(strsplit(before$type, '_and_')))
strsplit
go użyjesz , utworzy pojedynczy wektor z 2 wartościami w każdym gnieździe, więctstrsplit
transponuje go na 2 wektory z jedną wartością w każdym.paste0
służy tylko do tworzenia nazw kolumn, nie jest używany w wartościach. Na LHS równania są nazwy kolumn, na RHS operacja podziału + transpozycji na kolumnie.:=
oznacza „ przypisać na miejscu ”, dlatego nie widać<-
tam operatora przypisania.Jeszcze inne podejście: użyj
rbind
naout
:I połączyć:
źródło
strcapture("(.*)_and_(.*)", as.character(before$type), data.frame(type_1 = "", type_2 = ""))
Zauważ, że sapply z „[” może być użyty do wyodrębnienia pierwszego lub drugiego elementu z tych list, więc:
A oto metoda gsub:
źródło
oto jedna linijka wzdłuż tych samych linii co rozwiązanie aniko, ale przy użyciu pakietu stringr Hadleya:
źródło
stringr
pakiecie.Aby dodać do opcji, możesz również użyć mojej
splitstackshape::cSplit
funkcji w następujący sposób:źródło
Prostym sposobem jest użycie
sapply()
i[
funkcja:Na przykład:
sapply()
Wynikiem jest matryca, która wymaga transpozycji i przeniesienia z powrotem do ramki danych. Są to wtedy proste manipulacje, które dają pożądany rezultat:W tym momencie
after
jest to, czego chciałeśźródło
Temat jest prawie wyczerpany, chciałbym jednak zaproponować rozwiązanie nieco bardziej ogólnej wersji, w której a priori nie znasz liczby kolumn wyjściowych. Na przykład masz
Nie możemy użyć dplyr,
separate()
ponieważ nie znamy liczby kolumn wynikowych przed podziałem, więc stworzyłem funkcję, która używastringr
do dzielenia kolumny, biorąc pod uwagę wzorzec i prefiks nazwy dla wygenerowanych kolumn. Mam nadzieję, że zastosowane wzorce kodowania są prawidłowe.Następnie możemy użyć
split_into_multiple
w rurze Dplyr w następujący sposób:A potem możemy użyć
gather
do uporządkowania ...źródło
Oto podstawowa linijka R, która nakłada się na szereg poprzednich rozwiązań, ale zwraca ramkę data.frame z właściwymi nazwami.
Używa go
strsplit
do rozbicia zmiennej i zadata.frame
pomocądo.call
/rbind
do ponownego umieszczenia danych w ramce data.frame. Dodatkowym dodatkowym ulepszeniem jestsetNames
dodanie nazw zmiennych do data.frame.źródło
To pytanie jest dość stare, ale dodam rozwiązanie, które uważam obecnie za najprostsze.
źródło
Od wersji R 3.4.0 można korzystać
strcapture()
z pakietu utils (dołączonego do podstawowych instalacji R), wiążąc dane wyjściowe z innymi kolumnami.źródło
Innym podejściem, jeśli chcesz się trzymać,
strsplit()
jest użycieunlist()
polecenia. Oto rozwiązanie zgodne z tymi zasadami.źródło
podstawowy, ale prawdopodobnie wolny:
źródło
Oto inne podstawowe rozwiązanie R. Możemy użyć,
read.table
ale ponieważ akceptuje on tylkosep
argument jednobajtowy, a tutaj mamy separator wielobajtowy, którego możemy użyćgsub
do zastąpienia separatora wielobajtowego dowolnym separatorem jednobajtowym i użyć go jakosep
argumentu wread.table
W takim przypadku możemy również go skrócić, zastępując go domyślnym
sep
argumentem, abyśmy nie musieli wyraźnie o tym wspominaćźródło