You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言strsplit结果转字符变量及不规则空白数据清洗问题

Hey there! No worries about the oversight—irregular whitespace in strings can be a total pain. Let's tackle this step by step, simplifying your workflow and fixing those strsplit/validation issues.

Step 1: Load Required Packages

We'll stick with data.table (since you're already working with it) and use stringr for cleaner regex handling (it makes capturing groups way easier than nested base R functions).

library(data.table)
library(stringr)

Step 2: Define Your Data & Control List

Let's start with your updated dataset and control validation list:

df <- data.table(v=c( 
" 555 OUT XYZ STR44W PASSED TRUE", # Type1a
" A 45 OUT XYW STR44W PASSED TRUE", # Type1b
" 555 OUT XYZ STR55W PASSED TRUE", # Type1a
" 6755 OUT XYZ 4444W PASSED TRUE", # Type1a
" 75/850CC/PF ", # Erratic data to ignore
" BY HHU 56TT00 6 415 UP HHU 88H900 ", # Type2
" 555 OUT WWWZ STR44W PASSED TRUE" )) # Type1a

control <- data.table(control=c("XYZ","PPO","XMX","WWWZ"))

Step 3: Flag Data Types (T1, T2)

First, we'll mark which rows belong to Type1 (contains "PASSED TRUE") and Type2 (contains both "BY" and "UP"):

df[, `:=`(
  T1 = as.integer(str_detect(v, "PASSED TRUE")),
  T2 = as.integer(str_detect(v, "BY") & str_detect(v, "UP"))
)]

Step 4: Extract Type1 Fields (T1_V1, T1_V2, T1_V3)

Forget messy nested gsub and strsplit—use regex capture groups to directly pull the values you need. This avoids empty elements entirely:

# Regex pattern for Type1: captures OUT-before content, OUT-PASSED first block, OUT-PASSED second block
t1_pattern <- "^\\s*(.*?)\\s+OUT\\s+(\\S+)\\s+(\\S+)\\s+PASSED TRUE\\s*$"

# Extract capture groups into new columns (only for Type1 rows)
df[T1 == 1, `:=`(
  T1_V1 = str_trim(str_match(v, t1_pattern)[,2]), # Trim whitespace from OUT-before content
  T1_V2 = str_match(v, t1_pattern)[,3],
  T1_V3 = str_match(v, t1_pattern)[,4]
)]

Step 5: Validate T1_V3 Against Control List

Now fix that validation step—since T1_V3 is a plain character column (not a list), this is straightforward:

# Set non-matching T1_V3 values to NA
df[T1 == 1 & !T1_V3 %in% control$control, T1_V3 := NA_character_]

Step 6: Extract Type2 Fields (T2_V1 to T2_V5)

Use another regex pattern to capture the structured values in Type2 rows:

# Regex pattern for Type2: captures 4 blocks after BY, and content after UP
t2_pattern <- "^\\s*BY\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+UP\\s+(.*?)\\s*$"

df[T2 == 1, `:=`(
  T2_V1 = str_match(v, t2_pattern)[,2],
  T2_V2 = str_match(v, t2_pattern)[,3],
  T2_V3 = str_match(v, t2_pattern)[,4],
  T2_V4 = str_match(v, t2_pattern)[,5],
  T2_V5 = str_trim(str_match(v, t2_pattern)[,6]) # Trim whitespace from UP-after content
)]

Step 7: Fill NA for Non-Matching Rows

Finally, set NA values for all extracted columns where T1/T2 is 0:

# Fill NA for Type1 columns when T1 is 0
df[T1 == 0, `:=`(T1_V1 = NA_character_, T1_V2 = NA_character_, T1_V3 = NA_character_)]

# Fill NA for Type2 columns when T2 is 0
df[T2 == 0, `:=`(T2_V1 = NA_character_, T2_V2 = NA_character_, T2_V3 = NA_character_, 
                 T2_V4 = NA_character_, T2_V5 = NA_character_)]

Step 8: View the Final Output

Reorder columns to match your desired format:

setcolorder(df, c("T1", "T2", "T1_V1", "T1_V2", "T1_V3", "T2_V1", "T2_V2", "T2_V3", "T2_V4", "T2_V5"))
print(df)

You'll get exactly the output you wanted:

T1 T2 T1_V1 T1_V2 T1_V3 T2_V1 T2_V2 T2_V3 T2_V4 T2_V5
1:  1  0   555   XYZ STR44W    NA    NA    NA    NA    NA
2:  1  0  A 45   XYW STR44W    NA    NA    NA    NA    NA
3:  1  0   555   XYZ STR55W    NA    NA    NA    NA    NA
4:  1  0  6755   XYZ 4444W    NA    NA    NA    NA    NA
5:  0  0     NA    NA    NA    NA    NA    NA    NA    NA
6:  0  1     NA    NA    NA   HHU 56TT00     6   415 HHU 88H900
7:  1  0   555  WWWZ STR44W    NA    NA    NA    NA    NA

Why This Works Better Than Your Original Approach

  • No messy gsub chains: Regex capture groups pull exactly what you need in one go.
  • No empty elements: We target non-whitespace sequences (\\S+) so we only get valid values.
  • Clean validation: Plain character columns make checking against the control list simple with %in%.
  • Efficient data.table operations: Using := modifies columns in-place, which is faster for large datasets.

内容的提问来源于stack exchange,提问作者rolling r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:48:19