用于导入数据集和管道的 R 函数根据字段 name/existence 创建变量
R Function to import data set and pipeline create variables based on field name/existence
我正在创建一个函数来自动导入多个数据集,但在管道中分配变量值时遇到困难。
任务:
我有 20 多个数据集需要导入并计算和创建相同的变量。输入数据集包含相同的字段,除了一个字段,其名称可以是三个可能值之一('varYEAR',其中 'YEAR' 是三个可能的年份之一),但其基础数据是同一类型。我试图将此 varYEAR 向量的值分配给一个统一命名的变量 'varXXXX' ,以便进一步的突变可以引用后一个变量而不必担心原始变量名称。下面的代码已经过简化,以关注问题的症结所在。
当前示例 Code/Output:
set_import <- function(input_path,year) {
temp_set <- read_table(input_path) %>%
mutate(MSAXXXX = ifelse(exists('var2003'),var2003,var2013))
}
View(temp_set)
var2003 varXXXX
1 41929 41929
2 33820 41929
3 27642 41929
4 88111 41929
为此我尝试了几种不同的方法,包括:
mutate(varXXXX = ifelse('var2003' %in% names(.),var2003,var2013))
以及使用 temp_set$MSAXXXX = as.character(ifelse('var2003' %in% names(temp_set),temp_set$var2003,var2013))
在管道外进行尝试。每个都产生了上面相同的输出集。
期望输出:
View(temp_set)
var2003 varXXXX
1 41929 41929
2 33820 33820
3 27642 27642
4 88111 88111
我现在可以推测的最好结果是 'if' 语句基于单个检查,并且出于某种原因,它使用在所述检查中找到的第一个值填充 varXXXX 字段。我不知所措,非常感谢您的帮助!提前致谢。
解决方案
只需使用regex更改列名:
temp_set <- read_table(input_path)
names(temp_set) <- gsub(x = names(temp_set), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX")
或等效于 `names<-`()
in the dplyr
工作流程:
temp_set <- read_table(input_path) %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
正则表达式
pattern = "^(.+)(\d{4,4})$"
将每个名字分成两个 capturing groups:
- 任何正长度的前缀:
.+
- 某个年份由
4
位数字组成:\d{4,4}
然后 replacement = "\1XXXX"
将第一组 (\1
) 添加到代码 (XXXX
) 之前;所以代码基本上“取代”了年份。
例子
这里有两种可能的情况,其中 MSAXXXX
列分别以 MSA2003
和 MSA2013
开始:
case_1 <- data.frame(
MSA2003 = c(41929, 33820, 27642, 88111),
var2019 = c(41929, 33820, 27642, 88111),
other_var = 1:4
)
case_1
#> MSA2003 var2019 other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
case_2 <- data.frame(
MSA2013 = c(41929, 33820, 27642, 88111),
var2009 = c(41929, 33820, 27642, 88111),
other_var = 1:4
)
case_2
#> MSA2013 var2009 other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
请注意解决方案如何标准化名称中包含年份的所有变量,同时保持其他变量不变:
library(dplyr)
case_1 %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
#> MSAXXXX varXXXX other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
case_2 %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
#> MSAXXXX varXXXX other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
我正在创建一个函数来自动导入多个数据集,但在管道中分配变量值时遇到困难。
任务:
我有 20 多个数据集需要导入并计算和创建相同的变量。输入数据集包含相同的字段,除了一个字段,其名称可以是三个可能值之一('varYEAR',其中 'YEAR' 是三个可能的年份之一),但其基础数据是同一类型。我试图将此 varYEAR 向量的值分配给一个统一命名的变量 'varXXXX' ,以便进一步的突变可以引用后一个变量而不必担心原始变量名称。下面的代码已经过简化,以关注问题的症结所在。
当前示例 Code/Output:
set_import <- function(input_path,year) {
temp_set <- read_table(input_path) %>%
mutate(MSAXXXX = ifelse(exists('var2003'),var2003,var2013))
}
View(temp_set)
var2003 varXXXX
1 41929 41929
2 33820 41929
3 27642 41929
4 88111 41929
为此我尝试了几种不同的方法,包括:
mutate(varXXXX = ifelse('var2003' %in% names(.),var2003,var2013))
以及使用 temp_set$MSAXXXX = as.character(ifelse('var2003' %in% names(temp_set),temp_set$var2003,var2013))
在管道外进行尝试。每个都产生了上面相同的输出集。
期望输出:
View(temp_set)
var2003 varXXXX
1 41929 41929
2 33820 33820
3 27642 27642
4 88111 88111
我现在可以推测的最好结果是 'if' 语句基于单个检查,并且出于某种原因,它使用在所述检查中找到的第一个值填充 varXXXX 字段。我不知所措,非常感谢您的帮助!提前致谢。
解决方案
只需使用regex更改列名:
temp_set <- read_table(input_path)
names(temp_set) <- gsub(x = names(temp_set), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX")
或等效于 `names<-`()
in the dplyr
工作流程:
temp_set <- read_table(input_path) %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
正则表达式
pattern = "^(.+)(\d{4,4})$"
将每个名字分成两个 capturing groups:
- 任何正长度的前缀:
.+
- 某个年份由
4
位数字组成:\d{4,4}
然后 replacement = "\1XXXX"
将第一组 (\1
) 添加到代码 (XXXX
) 之前;所以代码基本上“取代”了年份。
例子
这里有两种可能的情况,其中 MSAXXXX
列分别以 MSA2003
和 MSA2013
开始:
case_1 <- data.frame(
MSA2003 = c(41929, 33820, 27642, 88111),
var2019 = c(41929, 33820, 27642, 88111),
other_var = 1:4
)
case_1
#> MSA2003 var2019 other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
case_2 <- data.frame(
MSA2013 = c(41929, 33820, 27642, 88111),
var2009 = c(41929, 33820, 27642, 88111),
other_var = 1:4
)
case_2
#> MSA2013 var2009 other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
请注意解决方案如何标准化名称中包含年份的所有变量,同时保持其他变量不变:
library(dplyr)
case_1 %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
#> MSAXXXX varXXXX other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4
case_2 %>%
`names<-`(gsub(x = names(.), pattern = "^(.+)(\d{4,4})$", replacement = "\1XXXX"))
#> MSAXXXX varXXXX other_var
#> 1 41929 41929 1
#> 2 33820 33820 2
#> 3 27642 27642 3
#> 4 88111 88111 4