你好,我有一个示例数据集如下。
# Load the tidyverse package
library(tidyverse)
# Create the dataset
id <- 1:6
model <- c("0RB3211", NA, "0RB4191",
NA, "0RB4033", NA)
UPC <- c("805289119081", "DK_0RB3447CP_RBCP 50", "8053672006360",
"Green_Classic_G-15_Polar_1.67_PREM_SV", "805289044604",
"DK_0RB2132CP_RBCP 55")
df <- tibble(id, model, UPC)
对于'model'列中的缺失值,如果其对应的UPC以DK开头,我需要提取7位数字和第一个下划线后的字母,然后将其放入'model'列中。例如,对于第二行,我需要将“0RB3447”放入“型号”列,对于第四行,我需要删除整行,对于最后一行,我需要将“0RB2132”放入'模特专栏。
# Manipulate the dataset
df_cleaned <- df %>%
rowwise() %>%
mutate(model = ifelse(is.na(model) & str_detect(UPC, "^DK"),
str_extract(UPC, "\\d{2}RB\\d{4}"),
model)) %>%
ungroup() %>%
filter(!(is.na(model) & str_detect(UPC, "[^0-9]")))
# Display the cleaned dataset
print(df_cleaned)
如何修改我以前的代码? 真的很感激。
而不是
ifelse
,另一种选择是coalesce
与现有的model
,这样它只用用str_replace
提取的UPC的子字符串替换模型中的NA。稍后仅保留模型以 0. 开头的行
library(dplyr)
library(stringr)
df %>%
mutate(model = coalesce(model,
str_replace(UPC, ".*_(0[^_]+\\d+)[A-Z]+_.*", "\\1"))) %>%
filter(str_detect(model, "^0"))
-输出
# A tibble: 5 × 3
id model UPC
<int> <chr> <chr>
1 1 0RB3211 805289119081
2 2 0RB3447 DK_0RB3447CP_RBCP 50
3 3 0RB4191 8053672006360
4 5 0RB4033 805289044604
5 6 0RB2132 DK_0RB2132CP_RBCP 55
在OP的代码中,不需要
rowwise
,因为ifelse
是矢量化的。此外,\\d{2}
不会像 0RB..
那样匹配某些字符串,只显示一个数字而不是 RB 前的 2。因此,用+
表示一个或多个数字
df %>%
mutate(model = ifelse(is.na(model) & str_detect(UPC, "^DK"),
str_extract(UPC, "(?<=_)\\d+RB\\d{4}"),
model)) %>%
filter(complete.cases(model))
-输出
# A tibble: 5 × 3
id model UPC
<int> <chr> <chr>
1 1 0RB3211 805289119081
2 2 0RB3447 DK_0RB3447CP_RBCP 50
3 3 0RB4191 8053672006360
4 5 0RB4033 805289044604
5 6 0RB2132 DK_0RB2132CP_RBCP 55
我也无法让
str_match
工作,但我确实想出了一个解决方法:
df_cleaned <- df %>%
rowwise() %>%
mutate(model = case_when(is.na(model) & grepl("DK", UPC) ~ str_split(UPC, "_")[[1]][2],
TRUE ~ model)) %>%
ungroup() %>%
filter(!(is.na(model) & str_detect(UPC, "[^0-9]")))
grepl
检测“DK”是否在 UPC 中。 str_split
创建一个包含 1 个项目的列表,其中三个字符串由下划线 (_) 分隔。你想要第二个项目,因此str_split(UPC, "_")[[1]][2]
.
此外,我发现
case_when()
是 ifelse()
的更清洁替代品。它像一样工作
case_when([if statement] ~ [then statement],
TRUE ~ [then statement])
其中 TRUE 本质上意味着“如果以上都不是真的”。
输出:
# A tibble: 5 × 3
id model UPC
<int> <chr> <chr>
1 1 0RB3211 805289119081
2 2 0RB3447CP DK_0RB3447CP_RBCP 50
3 3 0RB4191 8053672006360
4 5 0RB4033 805289044604
5 6 0RB2132CP DK_0RB2132CP_RBCP 55