Tách các hàng thành các cột bằng ký tự phân tách đầu tiên


8

Có một khung dữ liệu như thế này:

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

Làm thế nào có thể tách bằng cách sử dụng đầu tiên: trong mỗi hàng? Ví dụ sản lượng dự kiến

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

1
Điều này có trả lời câu hỏi của bạn không? Chia cột chuỗi khung dữ liệu thành nhiều cột
Claudiu Papasteri

2
@ClaudiuPapasteri không. Điều đó không hoàn toàn giống nhau và thực tế là giải pháp được chấp nhận hoạt động ở đây là tình cờ. Lừa đảo với những gì bạn đề xuất có thể rất sai lệch
Sotos

@ Hình ảnh có bạn đúng. Tôi đã không chú ý, hai trong số các giải pháp hoạt động nhưng tình cờ. Xin lỗi vì điều đó. Tôi đã thêm hai xu của mình vào nhóm giải pháp là lời xin lỗi vì cờ sai.
Claudiu Papasteri

Câu trả lời:


4
library(reshape2)

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

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

5

Trong cơ sở, bạn có thể sử dụng regexprđể tìm vị trí đầu tiên :có thể được sử dụng để trích xuất các chuỗi con và trimwsđể loại bỏ các khoảng trắng.

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

Bạn có thể sử dụng str_split_fixedtừ stringrgói sẽ được chia theo mặc định trên dấu phân cách đầu tiên, nghĩa là

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

Sử dụng 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

Một giải pháp cơ sở R khác

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

như vậy mà

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

2

Xin lỗi, @Sotos đúng, đây không phải là bản sao. Đây là một giải pháp cơ bản khác tách ra khi xuất hiện lần đầu tiên của dấu phân cách.

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

Được tạo vào ngày 2020 / 02-10 bởi gói reprex (v0.2.1)


2

Người nghèo ?utils::strcapturekhông bao giờ được tôn trọng:

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

Chèn lại:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.