R 如何跨多个CSV测试特定列名的存在性
我有大约60个要合并的R 如何跨多个CSV测试特定列名的存在性,r,string,csv,merge,names,R,String,Csv,Merge,Names,我有大约60个要合并的csv文件。一个挑战是列的命名不一致,尽管实际上所有文件(应该)都有相同的数据 为了解决这个问题,我想首先测试哪些文件有特定的列名(哪些没有)。我有一个字符串向量,其中每个元素反映一个列名,要检查它是否存在于每个csv文件中 我正在尝试实现一个数据帧,该数据帧将具有: 列:每列对应一个我要测试是否存在的列名 行:每行对应一个csv文件 值:在每个单元格中,使用0或1标记csv文件是否具有列名 例如,3个CSV 库(tidyverse) df_1如果您只希望列的索引与co
csv
文件。一个挑战是列的命名不一致,尽管实际上所有文件(应该)都有相同的数据
为了解决这个问题,我想首先测试哪些文件有特定的列名(哪些没有)。我有一个字符串向量,其中每个元素反映一个列名,要检查它是否存在于每个csv文件中
我正在尝试实现一个数据帧,该数据帧将具有:
- 列:每列对应一个我要测试是否存在的列名
- 行:每行对应一个csv文件
- 值:在每个单元格中,使用
或0
标记csv文件是否具有列名1
库(tidyverse)
df_1如果您只希望列的索引与col_names_to_test
匹配,可以使用以下方法:
library('data.table')
library('dplyr')
col_names_to_test = c('date', 'name', 'age', 'age_value', 'gender')
# define columns indexes matching the pattern
DefCols = function(input_path, patterns) {
pattern = patterns %>%
str_flatten('|')
cols = input_path %>%
fread(nrows = 1) %>%
colnames() %>%
str_which(pattern)
return(cols)
}
# define the input directory
input_dir = ''
cols = input_dir %>%
dir(pattern = '.*.csv$', full.names = TRUE, recursive = TRUE) %>%
lapply(DefCols, col_names_to_test)
但是,如果还希望仅加载具有匹配列的数据帧,则可以对其进行扩展,如下所示:
library('data.table')
library('dplyr')
col_names_to_test = c('date', 'name', 'age', 'age_value', 'gender')
# define columns indexes matching the pattern
LoadDF = function(input_path, patterns) {
pattern = patterns %>%
str_flatten('|')
cols = input_path %>%
fread(nrows = 1) %>%
colnames() %>%
str_which(pattern)
df = input_path %>%
fread(drop = -cols) %>%
as.data.frame()
return(df)
}
# define the input directory
input_dir = ''
dfs = 'input_dir' %>%
dir(pattern = '.*.csv$', full.names = TRUE, recursive = TRUE) %>%
lapply(LoadDF, col_names_to_test)
注意:当我加载数据以检查列名时,我只保留第一行(nrows=1
),因为我不关心每个单元格中的值。定义一个函数ok
,该函数给定的文件名f
返回一个命名的0/1向量,该向量的长度与col\u names\u to\u test
的相应组件作为列名存在于该文件中,则返回1,否则返回0。然后定义文件名向量文件
。为其命名,不带扩展名,并使用map\u dfr
对其应用ok
这相当紧凑,仅使用purrr
library(purrr)
ok <- function(f) +setNames(col_names_to_test %in% names(read.csv(f)), col_names_to_test)
files <- Sys.glob("csv_*.csv")
shortnames <- sub("\\.csv$", "", basename(files))
files %>% setNames(shortnames) %>% map_dfr(ok, .id = "file")
库(purrr)
好的,太棒了。我只想补充一点,在我的例子中,我将文件
与文件一起分配,您是否介意解释+
在集合名
之前在函数ok
中的作用,该函数将逻辑向量转换为0/1向量。试试+c(TRUE,FALSE)
也在处理完整路径名的解决方案中添加了短名称行。我还有一个问题,我想知道是否需要单独的帖子或者可以添加到这里——调整ok
函数(或者创建ok\u 2
是否足够简单这样它也会返回1
进行部分匹配?例如,如果<代码> COLLYNAMESSUTASTest有<代码>年龄< /代码>,并且<代码> CVSy3有<代码> AGEL值> /代码>,我们将认为这是一个匹配,因为<代码> AGEJORIVE值包含<代码>年龄>代码>作为子串。如果我们不知道CSV中列名的确切措辞,但可以猜测“age”列可能至少有age
作为子字符串,那么这将非常有用。
# A tibble: 3 x 6
file date name age age_value gender
<chr> <int> <int> <int> <int> <int>
1 csv_1 1 1 1 0 1
2 csv_2 0 0 1 0 0
3 csv_3 1 1 0 1 1