【问题标题】:Is it possible to compare multiple .csv files contents in R是否可以在 R 中比较多个 .csv 文件的内容
【发布时间】:2021-01-11 04:53:27
【问题描述】:

假设我有一个包含 10 个 .csv 文件的文件夹,它们看起来像:

> df1
  apple Mary car
a     1    1   1
b     2    2   2
c     3    3   3
d     4    4   4
e     5    5   5

> df2
  apple Mary car
a     1    1   1
b     2    2   2
p     4    3   2
d     4    4   4
e     5    5   5

> df3
  phone Jognny car
a     1      1   1
b     2      2   2
c     3      3   3
p     4      3   4
e     5      5   5
i     1      2   3

我想知道 dfs 有多“相似”。例如,df1df2 在 colnames 中有 100% 的匹配,但在 rownames 中只有 80% 的匹配。因此,两个数据帧的匹配率约为 87%(13/15 数据内容元素)。 df2df3 只有 33% 的 colnames 匹配...等然后,df1df3...等

它类似于cor(),但有不同维度和列名的数据框......等等

生成数据的代码:

> dput(df1)
structure(list(apple = 1:5, Mary = 1:5, car = 1:5), class = "data.frame", row.names = c("a", 
"b", "c", "d", "e"))
> dput(df2)
structure(list(apple = c(1, 2, 4, 4, 5), Mary = c(1, 2, 3, 4, 
5), car = c(1, 2, 2, 4, 5)), row.names = c("a", "b", "p", "d", 
"e"), class = "data.frame")
> dput(df3)
structure(list(phone = c(1, 2, 3, 4, 5, 1), Jognny = c(1, 2, 
3, 3, 5, 2), car = c(1, 2, 3, 4, 5, 3)), row.names = c("a", "b", 
"c", "p", "e", "i"), class = "data.frame")

【问题讨论】:

    标签: r


    【解决方案1】:

    您始终可以查看一个数据帧中的行名,这些行名也是另一个数据帧的行名:

    table(colnames(df1) %in% colnames(df2))*100/ncol(df1)
    #> TRUE 
    #>  100 
    
    table(rownames(df1) %in% rownames(df2))*100/nrow(df1)
    #> FALSE  TRUE 
    #>    20    80 
    

    因此,您的“相似性度量”是有多少单元格具有相同的行名和列名,除以有多少单元格。单元格数是行数和列数的乘积;名称匹配的单元格数是名称匹配的行数和列数的乘积:

    sum(rownames(df1) %in% rownames(df2)) * sum(colnames(df1) %in% colnames(df2))
    #> [1] 12
    nrow(df1)*ncol(df1)
    #> [1] 15
    
    100*sum(rownames(df1) %in% rownames(df2)) * sum(colnames(df1) %in% colnames(df2))/(nrow(df1)*ncol(df1))
    #> [1] 80
    
    compare_names <- function(x, y){
      100*sum(rownames(x) %in% rownames(y)) * sum(colnames(x) %in% colnames(y))/(nrow(x)*ncol(x))
    }
    
    compare_names(df1, df2) 
    #> [1] 80
    

    请注意,它并不总是对称的(因为 df1df3 具有不同数量的单元格,因此它们的匹配单元格名称比例不同):

    compare_names(df1, df3) 
    #> [1] 26.66667
    compare_names(df3, df1) 
    #> [1] 22.22222
    

    当然,这里我们只是比较行名和列名,你没有提到你的问题中值的相似性。


    对于每个组合,我想到的最简单的是两个 for 循环:

    all_df <- setNames(list(df1, df2, df3),
                       c("df1", "df2", "df3"))
    
    mat_similarities <- matrix(NA_real_,
                  nrow=length(all_df),
                  ncol=length(all_df),
                  dimnames = list(names(all_df),
                                  names(all_df)))
    
    for(i in names(all_df)){
      for(j in names(all_df)){
        mat_similarities[i,j] <- compare_names(all_df[[i]],
                                               all_df[[j]])
      }
    }
    
    round(mat_similarities)
    #>     df1 df2 df3
    #> df1 100  80  27
    #> df2  80 100  27
    #> df3  22  22 100
    

    【讨论】:

    • 嗨,如果我也对值的相似性感兴趣怎么办?
    • 您可以使用unlist() 获取所有值,然后像之前一样将它们与%in% 匹配。如果您不仅要匹配值,还要比较相对差异,这会变得更加复杂,您需要明确要将哪些值与其他值进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多