Разделите строки на столбцы, используя первый разделенный символ - PullRequest
8 голосов
/ 10 февраля 2020

Имея такой фрейм данных:

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

Как можно разделить, используя первый: в каждой строке? Пример ожидаемого результата

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

Ответы [ 8 ]

5 голосов
/ 10 февраля 2020

В base вы можете использовать regexpr, чтобы найти позицию первого :, который можно использовать для извлечения подстрок, и trimws, чтобы удалить пробелы.

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 голосов
/ 10 февраля 2020

Использование тидир :

library(dplyr)
library(tidyr)

df %>% 
  separate(text, c("a", "b"), sep = ": ", extra = "merge")
#            a         b
# 1  separate1 and: more
# 2 another 20        42
4 голосов
/ 10 февраля 2020
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 голосов
/ 10 февраля 2020

Вы можете использовать str_split_fixed из stringr пакета, который по умолчанию будет разделен на первый разделитель, т.е.

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

#     [,1]         [,2]        
#[1,] "separate1"  " and: more"
#[2,] "another 20" " 42"       
4 голосов
/ 10 февраля 2020
library(reshape2)

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

colsplit(df$text, ":", c("text1", "text2"))
3 голосов
/ 10 февраля 2020

Другое базовое решение R

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

такое, что

> df
       text1      text2
1  separate1  and: more
2 another 20         42
2 голосов
/ 11 февраля 2020

Бедный старик ?utils::strcapture никогда не получает никакого уважения:

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

Вставлен обратно:

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
2 голосов
/ 10 февраля 2020

Извините, @Сотос прав, это не дубликат. Вот еще одно базовое решение, которое разделяется при первом появлении разделителя.

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

Создано в 2020-02-10 пакетом Представления (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...