首页 > 解决方案 > 在 R 中“分隔”一列的更简洁的选项(可能通过一些正则表达式)?

问题描述

我有一个数据框,我想在其中分隔包含月份和年份的列:

library(tidyverse)
df <- data.frame(
  month_year = c("Januar / Janvier 1990", "Februar / Février 1990","März / Mars 1990")
)

# df
#               month_year
# 1  Januar / Janvier 1990
# 2 Februar / Février 1990
# 3       März / Mars 1990

以下工作,但似乎有点笨拙:

df %>% 
  separate(month_year, c("month","nothing","nothing2", "year"), sep = " ") %>%
  select(-starts_with("nothing"))

#     month year
# 1  Januar 1990
# 2 Februar 1990
# 3    März 1990

是否有更简洁的选择来实现相同的结果?

标签: rtidyverse

解决方案


1)单独使用 NA 省略不需要的字段,如下所示:

library(tidyr)

df %>% separate(month_year, c("month", NA, "year"))
##     month year
## 1  Januar 1990
## 2 Februar 1990
## 3    März 1990

@Otto 指出这在 UTF8 中存在问题。如果这是您的情况,请添加显示的 sep= 值。 separate使用"[^[:alnum:]]+"不处理 UTF8 的默认值,但我们可以指定其中任何一个来代替:

  • "[^\\p{L}\\d]+". 这将替换"[:alnum:]""\\p{L}"which 是任何语言的任何字母和"\\d"which 是任何数字,或
  • "(*UCP)[^[:alnum:]]+"它使用 unicode 说明符作为前缀

这显示了一个例子。首先,我们创建一个显示问题的输入 df2,然后我们使用上述两个 sep 值之一。

df <- data.frame(
  month_year = c("Januar / Janvier 1990", "Februar / Février 1990","März / Mars 1990"))
df2 <- df %>% mutate(month_year = iconv(month_year, to = "UTF8"))

df2 %>% separate(month_year, c("month", NA, "year"), sep = "[^\\p{L}\\d]+")
##     month year
## 1  Januar 1990
## 2 Februar 1990
## 3    März 1990

2)read.table,这是一个基本的解决方案:

read.table(text = df[[1]], col.names = c("month", NA, NA, "year"))[-(2:3)]
##     month year
## 1  Januar 1990
## 2 Februar 1990
## 3    März 1990

3) read.pattern这使用 read.pattern 挑选出所需的字段。(\\w+)捕获第一个单词并(\\d+)捕获年份。

library(gsubfn)

pat <- "(\\w+).* (\\d+)"
read.pattern(text = df[[1]], pattern = pat, col.names = c("month", "year"))
##     month year
## 1  Januar 1990
## 2 Februar 1990
## 3    März 1990

推荐阅读