Trennen Sie Zeilen mit dem ersten geteilten Zeichen in Spalten

8

Einen Datenrahmen wie diesen haben:

data.frame(text = c("separate1: and: more","another 20: 42")

Wie ist es möglich, mit dem ersten zu trennen: in jeder Zeile? Beispiel erwartete Ausgabe

data.frame(text1 = c("separate1","another 20"), text2 = c("and: more","42")
Nathalie
quelle
1
Beantwortet das deine Frage?
Teilen Sie die
2
@ClaudiuPapasteri nein. Das ist nicht genau das gleiche und die Tatsache, dass die akzeptierte Lösung hier funktioniert, ist zufällig. Das Betrügen mit dem, was Sie vorschlagen, kann sehr irreführend sein
Sotos
@Sotos ja du hast recht. Ich habe nicht aufgepasst, zwei der Lösungen funktionieren aber zufällig. Das tut mir leid. Ich habe meine zwei Cent als Entschuldigung für die falsche Flagge zum Lösungspool hinzugefügt.
Claudiu Papasteri

Antworten:

4
library(reshape2)

df <- data.frame(text = c("separate1: and: more","another 20: 42")

colsplit(df$text, ":", c("text1", "text2"))
Georgery
quelle
5

In base können regexprSie die Position der ersten :ermitteln, mit der Teilzeichenfolgen extrahiert und trimwsLeerzeichen entfernt werden können.

x <- c("separate1: and: more","another 20: 42")

i <- regexpr(":", x)
data.frame(text1 = trimws(substr(x, 1, i-1)), text2 = trimws(substring(x, i+1)))
#       text1     text2
#1  separate1 and: more
#2 another 20        42
GKi
quelle
4

Sie können mit str_split_fixedaus - stringrPaket , das standardmäßig Split auf dem ersten Begrenzer wird, dh

stringr::str_split_fixed(d1$text, ':', 2)

#     [,1]         [,2]        
#[1,] "separate1"  " and: more"
#[2,] "another 20" " 42"       
Sotos
quelle
4
df <- data.frame(text = c("separate1: and: more","another 20: 42"))

df$text1 <- gsub(':.*', '', df$text)
df$text2 <- gsub('^[^:]+: ', '', df$text)

df
#                   text      text1     text2
# 1 separate1: and: more  separate1 and: more
# 2       another 20: 42 another 20        42
IceCreamToucan
quelle
4

Mit tidyr :

library(dplyr)
library(tidyr)

df %>% 
  separate(text, c("a", "b"), sep = ": ", extra = "merge")
#            a         b
# 1  separate1 and: more
# 2 another 20        42
zx8754
quelle
3

Eine andere Basis-R-Lösung

df <- do.call(rbind,lapply(as.character(df$text), function(x) {
  k <- head(unlist(gregexpr(":",x)),1)
  data.frame(text1 = substr(x,1,k-1),
             text2 = substr(x,k+1,nchar(x)))
}))

so dass

> df
       text1      text2
1  separate1  and: more
2 another 20         42
ThomasIsCoding
quelle
2

Entschuldigung, @Sotos hat recht, dies ist kein Duplikat. Hier ist eine weitere Basislösung, die sich beim ersten Auftreten eines Trennzeichens aufteilt.

df <- data.frame(text = c("separate1: and: more","another 20: 42"))

list <- apply(df, 1, function(x) regmatches(x, regexpr(":", x), invert = TRUE))
df <- data.frame(matrix(unlist(list), nrow = length(list), byrow = TRUE))

df
#>           X1         X2
#> 1  separate1  and: more
#> 2 another 20         42

Erstellt am 2020-02-10 durch das reprex-Paket (v0.2.1)

Claudiu Papasteri
quelle
2

Der arme Alte ?utils::strcapturebekommt nie Respekt:

strcapture("^(.+?):(.+$)", df$text, proto=list(text1="", text2=""))
#       text1      text2
#1  separate1  and: more
#2 another 20         42

Zurück eingefügt:

cbind(df, strcapture("^(.+?):(.+$)", df$text, proto=list(text1="", text2="")))
#                  text      text1      text2
#1 separate1: and: more  separate1  and: more
#2       another 20: 42 another 20         42
die E-Mail
quelle