【问题标题】:How to count the number of "unique columns" in each csv in R如何计算R中每个csv中“唯一列”的数量
【发布时间】:2016-01-23 02:17:20
【问题描述】:

我是 R 的新用户。我需要您的建议 - 我有大约 100 个 csv 文件。每个文件中的列数可以更改。我正在寻找帮助识别每个文件中“唯一列”的数量 - (如果文件有重复的列,我希望它算作 1 个唯一列)

file1.csv

a,b,c,d
1,2,0,4
2,0,3,5
3,0,4,6
4,8,7,0

file2.csv

a,b,c,d,c
1,2,0,3,0
2,3,4,5,4
3,6,2,0,2
4,2,3,5,3

所以从技术上讲,代码应该为 file1.csv 提供 4 列(a、b、c、d),为 file2.csv 提供 4 列(a、b、c、d - c 列重复)。我知道使用 dim(df)[2] 会给我每个文件中的列数,但如果我必须为 100 个文件执行此操作,我应该怎么做?

【问题讨论】:

  • 谢谢 nrussel,你是怎么安排这些桌子的?
  • 我只是将它们格式化为代码 - 选择一段文本并单击花括号符号 ({}) 或按 Ctrl+K。
  • 当有重复的列时,列名是否也总是重复?
  • 如果它是重复的列,那么是的,名称也会重复

标签: r


【解决方案1】:

如果列名不仅仅是装饰:f 计算数据框的唯一列数X

f <- function( X )
{
  A <- mapply(c,as.list(X),colnames(X))

  sum( apply(A,2,function(col)
  {
    1 / sum( colSums( matrix(!(rep(col,ncol(A))==c(A)),nrow(A)) ) == 0 )
  } ) )
}

例子:

> X1 <- data.frame( a = 1:3, b = 5:7, c = 3:1, d = 9:7  )

> X2 <- cbind( X1, c=4:2 )

> X3 <- cbind( X1, c=1:3 )

> X4 <- cbind( X1, e=5:7 )

> X5 <- cbind( X1, b=5:7 )
> X1
  a b c d
1 1 5 3 9
2 2 6 2 8
3 3 7 1 7
> X2
  a b c d c
1 1 5 3 9 4
2 2 6 2 8 3
3 3 7 1 7 2
> X3
  a b c d c
1 1 5 3 9 1
2 2 6 2 8 2
3 3 7 1 7 3
> X4
  a b c d e
1 1 5 3 9 5
2 2 6 2 8 6
3 3 7 1 7 7
> X5
  a b c d b
1 1 5 3 9 5
2 2 6 2 8 6
3 3 7 1 7 7
> 
> f(X1)
[1] 4
> f(X2)
[1] 5
> f(X3)
[1] 5
> f(X4)
[1] 5
> f(X5)
[1] 4
> f(cbind(X1,X1))
[1] 4
> f(cbind(X1,X5))
[1] 4
> f(cbind(X1,X2))
[1] 5
> f(cbind(X2,X3))
[1] 6
> 

【讨论】:

    【解决方案2】:

    如果列名足以确定重复的列,一种简单快捷的方法是使用readLines()读取每个文件的第一行,并根据文件分隔符(“,”)用@分割987654322@,然后求返回的唯一向量的长度。

    您可以将其包装在 sapplylapply 中以遍历文件列表。

    files <- c("file1.csv", "file2.csv")
    ncolumns <- sapply(files, function(f) {
        header.line <- readLines(f, n=1)
        length(unique(strsplit(header.line, ",")[[1]]))
    })
    ncolumns
    # file1.csv file2.csv 
    #         4         4 
    

    假设列名足以确定唯一性,这会更快,因为您不必加载整个 csv 文件。

    【讨论】:

    • 鉴于发帖者问题的性质,这似乎是最简洁和最完整的回答。
    【解决方案3】:

    我会使用一个循环来依次读取每个文件。您不想同时打开它们,否则可能会耗尽内存。

    获取文件列表:

    f = list.files("./dir/", pattern="csv")
    

    读取文件,查找唯一列并将结果写入变量:

    answer = sapply(f, function(i){
       # read the file
       x = read.csv(i)
       # extract column names and then get the unique ones
       x = unique(colnames(x))
       # return the number of column names
       length(x)
    })
    

    然后您可以查看文件长度:

    # Summary statistics
    summary(answer)
    # Boxplot
    boxplot(answer)
    # Plot of number of columns vs names (probably messy with 100)
    barplot(answer, names.arg=f)
    

    【讨论】:

      【解决方案4】:

      您可以尝试同时使用 length() 和 unique() 函数来计算唯一列名的数量。例如:

      data <- data.frame(matrix(c(1:12), nrow=3, ncol=4))
      colnames(data) <- c("a","b","c","b")
      
      length(unique(colnames(data)))
      

      根据您的上传过程,您可以尝试将其集成到循环中或作为批处理过程运行。

      【讨论】:

      • 感谢 JFu。只有当我知道每个文件中有多少行和列数时,您共享的命令才会对我有所帮助,对吗?如果我不知道怎么办?我有 100 个 csv 文件,行数可以是 1000,列数可以是 100
      • 嗨 SAS,如果您询问我代码中的第一行,那只是为了创建示例数据。只要您的文件是 R 中的对象(如数据框),您就可以使用 colnames() 来获取对象的列名。然后,length(unique()) 将为您提供唯一列名的数量。
      • 您的示例中的“b”列并不是真正重复的。
      猜你喜欢
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 2019-09-05
      • 2021-07-29
      相关资源
      最近更新 更多