>我有一个数据帧,我想在其中分隔包含月份和年份的列:
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
有没有更简洁的选项来实现相同的结果?
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}"
, 是任何语言的任何字母,"\d"
是任何数字,或"(*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
base R
strcapture("^(.*)\s+/.*\s+([^\s]+)$", df$month_year, proto = c(month="", year=1L))
# month year
# 1 Januar 1990
# 2 Februar 1990
# 3 März 1990
也许有点笨拙:
setNames(do.call(rbind.data.frame,
lapply(strsplit(df$month_year, "\s+"), function(z) z[c(1, length(z))])),
c("month", "year"))
德普利尔
使用不同的正则表达式对代码进行轻微的减少:
library(dplyr)
df %>%
separate(month_year, c("month", "ign", "year"), "[ /]+") %>%
select(-ign)
或
df %>%
mutate(month_year = gsub("/.* ", "", month_year)) %>%
separate(month_year, c("month", "year"), " ")
我们可以使用stringr
包中的word
:
library(dplyr)
library(stringr)
df %>%
mutate(month = word(month_year, 1),
year = word(month_year, 4), .keep="unused")
month year
1 Januar 1990
2 Februar 1990
3 März 1990
尝试使用以下基本 R 代码,其中包含read.table
+gsub
read.table(
text = c(names(df), gsub("\s+.*\s+", "_", df$month_year)),
sep = "_",
header = TRUE
)
这给了
month year
1 Januar 1990
2 Februar 1990
3 MΣrz 1990
Tidyverse + stringr
library(stringr)
df %>% mutate(year = as.numeric(str_extract(.$month_year, '\d+'))) %>%
mutate(month = str_extract(.$month_year, '[^ /]+') )
month_year year month
1 Januar / Janvier 1990 1990 Januar
2 Februar / Février 1990 1990 Februar
3 März / Mars 1990 1990 März
'\d+'
捕获所有数字;[^ /]
在第一次出现/
之前捕获子字符串。