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

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

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

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"       

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

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

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

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)


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.