Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中的随机数据中查找年份_R_Regex - Fatal编程技术网

在R中的随机数据中查找年份

在R中的随机数据中查找年份,r,regex,R,Regex,我在一个数据框中有71列,其中10列包含格式为YYYY(例如2019)的1990年至2019年之间的一年的数据。例如: id_1 <- c("regkfg_2013", "fsgdf-2014", "f2016sghsg", "gjdg1990_3759") id_2 <- c("dghdgl2013jg", "2fgdg_2014_hf", "ghdg_2016*89", "gc-hs1990") id_1有很多方法。这是其中之一: 步骤1:定义要与正则表达式匹配的模式: pat

我在一个数据框中有71列,其中10列包含格式为YYYY(例如2019)的1990年至2019年之间的一年的数据。例如:

id_1 <- c("regkfg_2013", "fsgdf-2014", "f2016sghsg", "gjdg1990_3759")
id_2 <- c("dghdgl2013jg", "2fgdg_2014_hf", "ghdg_2016*89", "gc-hs1990")

id_1有很多方法。这是其中之一:

步骤1:定义要与正则表达式匹配的模式:

pattern <- "(1|2)\\d{3}"
还有一种方法,实际上更简单;)

它使用
strungr
包中的
stru extract
函数。因此,您可以安装并激活该软件包:

install.packages("stringr")
library(stringr)
并使用
stru extract
提取匹配项:

years <- str_extract(id_1,"(1|2)\\d{3}") 
years
[1] "2013" "2014" "2016" "1990"
您可以如下设置
ifelse
测试:

dated_data <- select(undated_data, 1:71) %>% 
                filter(grepl("1990", id_1) | filter(grepl("1990", id_2) | filter(grepl("1991", id_1) | filter(grepl("1991", id_2)
years <- ifelse(grepl("(1|2)\\d{3}", id_3), str_extract(id_3,"(1|2)\\d{3}"), NA)
years
[1] "2013" "2014" "2016" "1990" NA     NA 

years有很多方法。这是其中之一:

步骤1:定义要与正则表达式匹配的模式:

pattern <- "(1|2)\\d{3}"
还有一种方法,实际上更简单;)

它使用
strungr
包中的
stru extract
函数。因此,您可以安装并激活该软件包:

install.packages("stringr")
library(stringr)
并使用
stru extract
提取匹配项:

years <- str_extract(id_1,"(1|2)\\d{3}") 
years
[1] "2013" "2014" "2016" "1990"
您可以如下设置
ifelse
测试:

dated_data <- select(undated_data, 1:71) %>% 
                filter(grepl("1990", id_1) | filter(grepl("1990", id_2) | filter(grepl("1991", id_1) | filter(grepl("1991", id_2)
years <- ifelse(grepl("(1|2)\\d{3}", id_3), str_extract(id_3,"(1|2)\\d{3}"), NA)
years
[1] "2013" "2014" "2016" "1990" NA     NA 

years根据您问题中的示例,您试图过滤掉任何没有年份的行,然后从字符串中提取年份。看起来每行只包含一年。下面是一些代码,这样您就不必为10列和30年编写长筛选语句。请记住,我没有您的数据,因此无法对其进行测试

library(tidyverse)

undated_data %>%
  select(1:71) %>%
  filter_at(vars(starts_with("id_"), any_vars(grepl(paste0(1990:2019, collapse = "|"), .)))) %>%
  mutate(year = str_extract(id_1, pattern = paste0(1990:2019, collapse = "|")))
编辑:根据你的评论,可能有些栏目有一年,而其他栏目没有。相反,我们要做的是将年份从具有
id.*
的任何列中拉出,然后
将这些列合并在一起。同样,如果没有您的数据,很难对其进行测试

undated_data %>%
  select(1:71) %>%
  filter_at(vars(starts_with("id_"), any_vars(grepl(paste0(1990:2019, collapse = "|"), .)))) %>%
  mutate_at(vars(starts_with("id_")), list(year = ~str_extract(., pattern = paste0(1990:2019, collapse = "|")))) %>%
  mutate(year = coalesce(ends_with("_year"))) %>%
  select(-ends_with("_year"))

根据问题中的示例,您试图过滤掉任何没有年份的行,然后从字符串中提取年份。看起来每行只包含一年。下面是一些代码,这样您就不必为10列和30年编写长筛选语句。请记住,我没有您的数据,因此无法对其进行测试

library(tidyverse)

undated_data %>%
  select(1:71) %>%
  filter_at(vars(starts_with("id_"), any_vars(grepl(paste0(1990:2019, collapse = "|"), .)))) %>%
  mutate(year = str_extract(id_1, pattern = paste0(1990:2019, collapse = "|")))
编辑:根据你的评论,可能有些栏目有一年,而其他栏目没有。相反,我们要做的是将年份从具有
id.*
的任何列中拉出,然后
将这些列合并在一起。同样,如果没有您的数据,很难对其进行测试

undated_data %>%
  select(1:71) %>%
  filter_at(vars(starts_with("id_"), any_vars(grepl(paste0(1990:2019, collapse = "|"), .)))) %>%
  mutate_at(vars(starts_with("id_")), list(year = ~str_extract(., pattern = paste0(1990:2019, collapse = "|")))) %>%
  mutate(year = coalesce(ends_with("_year"))) %>%
  select(-ends_with("_year"))

使用tidyverse方法:

undated_data %>% 
  mutate_at(vars(1:71), 
            funs(str_extract(., "(1|2)[0-9]{3}")))

(请注意,正则表达式模式将匹配可能不是年的数字,例如2999;如果您的数据有许多类似的“误报”,则最好编写一个自定义函数。)

使用tidyverse方法:

undated_data %>% 
  mutate_at(vars(1:71), 
            funs(str_extract(., "(1|2)[0-9]{3}")))

(请注意,正则表达式模式将匹配可能不是年的数字,例如2999;如果您的数据有许多类似的“误报”,您最好编写一个自定义函数。)

这里有一个类似于所提供的解决方案,但在
data.frame
上使用
dplyr
stringr

library(stringr)
library(dplyr)

df<-data.frame("X1" = id_1,"X2" = id_2)
#Set in cols the column names from which years are going to be extracted
df %>%
  pivot_longer(cols = c("X1","X2"), names_to = "id") %>%
  arrange(id) %>%
  mutate(new = unlist(str_extract_all(value, pattern = "(1|2)\\d{3}")))
库(stringr)
图书馆(dplyr)
df%
pivot_更长(cols=c(“X1”、“X2”),名称_to=“id”)%>%
排列(id)%>%
mutate(new=unlist(str_extract_all(value,pattern=“(1 | 2)\\d{3}”))

这里有一个与提供的解决方案类似的解决方案,但是在
数据帧上使用了
dplyr
stringr

library(stringr)
library(dplyr)

df<-data.frame("X1" = id_1,"X2" = id_2)
#Set in cols the column names from which years are going to be extracted
df %>%
  pivot_longer(cols = c("X1","X2"), names_to = "id") %>%
  arrange(id) %>%
  mutate(new = unlist(str_extract_all(value, pattern = "(1|2)\\d{3}")))
库(stringr)
图书馆(dplyr)
df%
pivot_更长(cols=c(“X1”、“X2”),名称_to=“id”)%>%
排列(id)%>%
mutate(new=unlist(str_extract_all(value,pattern=“(1 | 2)\\d{3}”))

这里可能有另一种解决方案

我们只需使用
gsub()
函数,并将模式设置为“(199[0-9]| 20[01][0-9])”

该模式将1990年至2019年间的一年文本作为 分组结果,特别是只有一个组,所以我们用第一个组字符串替换原始文本:)

库(magrittr)

id_1这里可能有另一种解决方案

我们只需使用
gsub()
函数,并将模式设置为“(199[0-9]| 20[01][0-9])”

该模式将1990年至2019年间的一年文本作为 分组结果,特别是只有一个组,所以我们用第一个组字符串替换原始文本:)

库(magrittr)
id_1R基溶液:

# Sample data: id_1; id_2 => character vectors
id_1 <- c("regkfg_2013", "fsgdf-2014", "f2016sghsg", "gjdg1990_3759")
id_2 <- c("dghdgl2013jg", "2fgdg_2014_hf", "ghdg_2016*89", "gc-hs1990")

# Thanks @Chris Ruehlemann: store the date pattern: date_pattern => character scalar
date_pattern <- "(1|2)\\d{3}"

# Convert to data.frame: df => data.frame 
df <- data.frame(id_1, id_2, stringsAsFactors = FALSE)

# Subset the data to only contain date information vectors: dates_subset => data.frame 
dates_subset <- df[,sapply(df, function(x){any(grepl(date_pattern, x))}), drop = FALSE]

# Initialse the year vector: year => character vector: 
df$years <- NA_character_

# Remove punctuation and letters, return valid dates, combine into a, comma-separated string:
# Store the dates found in the string: years => character vector 
df$years[which(rowSums(Vectorize(grepl)(date_pattern, dates_subset)) > 0)] <- 
  apply(sapply(dates_subset, function(x){
    grep(date_pattern,  unlist(strsplit(x, "[[:punct:]]|[a-zA-Z]")), value = TRUE)}), 
    1, paste, collapse = ", ")
#示例数据:id_1;id_2=>字符向量
id_1 0)]基本R溶液:

# Sample data: id_1; id_2 => character vectors
id_1 <- c("regkfg_2013", "fsgdf-2014", "f2016sghsg", "gjdg1990_3759")
id_2 <- c("dghdgl2013jg", "2fgdg_2014_hf", "ghdg_2016*89", "gc-hs1990")

# Thanks @Chris Ruehlemann: store the date pattern: date_pattern => character scalar
date_pattern <- "(1|2)\\d{3}"

# Convert to data.frame: df => data.frame 
df <- data.frame(id_1, id_2, stringsAsFactors = FALSE)

# Subset the data to only contain date information vectors: dates_subset => data.frame 
dates_subset <- df[,sapply(df, function(x){any(grepl(date_pattern, x))}), drop = FALSE]

# Initialse the year vector: year => character vector: 
df$years <- NA_character_

# Remove punctuation and letters, return valid dates, combine into a, comma-separated string:
# Store the dates found in the string: years => character vector 
df$years[which(rowSums(Vectorize(grepl)(date_pattern, dates_subset)) > 0)] <- 
  apply(sapply(dates_subset, function(x){
    grep(date_pattern,  unlist(strsplit(x, "[[:punct:]]|[a-zA-Z]")), value = TRUE)}), 
    1, paste, collapse = ", ")
#示例数据:id_1;id_2=>字符向量

id_1 0)]是否所有列都有一个名为
id_*
的潜在年份,是否每行只有一年,是否每行都有一年?您可以通过搜索具有4位数字的数字从基开始使用sub()或regexec()。更多信息是否所有列都有一个名为
id_*
的潜在年份,是否每行只有一年,每一行都有一年吗?你可以使用sub()或regexec()从基开始搜索有4位数字的数字查看更多这是完美的。非常感谢你!嘿,只有一个问题。有些列的匹配项少于行,因此,当我尝试将值添加到新列“year”时,会出现以下错误:
error in$this是完美的。非常感谢你!嘿,只有一个问题。有些列的匹配项少于行,因此,当我尝试将值添加到新列“year”时,会出现以下错误:
error in$这是一个很好的解决方案。谢谢嘿,非常感谢。只有一个问题-我得到了以下错误,因为不是每个单元格都有年份:
列年份的长度必须为1350(行数)或1,而不是940
。知道我该如何解决这个问题吗?有没有一个id变量有一年,而其他变量没有的情况?@Oliver我做了一个小小的调整更新了一下。如果您想在这方面获得更多帮助,我需要数据或数据的一小段。您可以使用
dput(head(未注明日期的_数据))
给出前10行。这是一个很好的解决方案。谢谢嘿,非常感谢。只有一个问题-我得到了以下错误,因为不是每个单元格都有年份:
列年份的长度必须为1350(行数)或1,而不是940
。知道我该怎么解决吗