4

我有许多结构相似的 .csv 文件:

1.csv

Type n
A   1
B   20
C   34
D   5
...

2.csv

Type n
A   2
B   15
C   16
D   5
...

我想将它们组合成类似的东西:

Type  n1   n2
  A   1    2
  B   20   15
  C   34   16
  D   5    5
  ...

当我使用 lapply 我得到

 Type n  Type   n
  A   1    A    2
  B   20   B    15
  C   34   C    16
  D   5    D    5
  ...

有什么简单的方法可以正确组合它们吗?

我愿意接受 R 或 Python 的解决方案

4

3 回答 3

3

解释 1:每个 CSV 的相同数据结构

如果结构相同,请考虑以下两个选项,但首先是一些示例数据:

cat("Type n", "A  1", "B  20", "C  34", "D  5", sep = "\n", file = "myfile1.txt")
cat("Type n", "A  2", "B  15", "C  16", "D  5", sep = "\n", file = "myfile2.txt")

选项 1:在读取数据时删除第一列,方法是使用"NULL"(带引号)作为colClasses需要删除的列。用于cbind将文件放在一起。

x <- read.table("myfile1.txt", header=TRUE)
y <- read.table("myfile2.txt", header=TRUE, colClasses=c("NULL", "numeric"))
cbind(x, y)
#   Type  n  n
# 1    A  1  2
# 2    B 20 15
# 3    C 34 16
# 4    D  5  5

## For more files:
## do.call(cbind, list(x, y, ...))

选项 2:正常读取文件,然后使用c(FALSE, TRUE)向量进行子集,将所有内容放入 a 中list,并cbind与任何对象的第一列一起。

x1 <- read.table("myfile1.txt", header = TRUE)
y1 <- read.table("myfile2.txt", header = TRUE)

fileList <- list(x1, y1)
cbind(x1[1], do.call(cbind, fileList)[c(FALSE, TRUE)])
#   Type  n n.1
# 1    A  1   2
# 2    B 20  15
# 3    C 34  16
# 4    D  5   5

当然,以上只是最小的例子。我假设您实际上在每个文件中有超过 2 列。使用与您的列实际匹配的TRUEs 和s 向量来保留和删除(分别)第二个选项,以及第一个选项的对象类。FALSE"NULL"


解读2:每个CSV的相似数据结构

如果数据结构相似但不相同,则可能需要merge改用。考虑以下示例数据。前三个文件具有相同的结构,但第四个文件"myfile4.txt"具有 A、B、D 和 E 作为“类型”值,而其他三个文件具有“A”、“B”、“C”和“D” "

cat("Type n", "A  1", "B  20", "C  34", "D  5", sep = "\n", file = "myfile1.txt")
cat("Type n", "A  2", "B  15", "C  16", "D  5", sep = "\n", file = "myfile2.txt")
cat("Type n", "A  1", "B   5", "C   6", "D  7", sep = "\n", file = "myfile3.txt")
cat("Type n", "A  8", "B   9", "D  11", "E  0", sep = "\n", file = "myfile4.txt")

以下是我们如何解决这个问题。

  1. 批量读取文件:

    x <- list.files(pattern="myfile")
    y <- lapply(x, read.table, header = TRUE)
    
  2. merge如果不能创建唯一名称,多个s 可能会导致错误。merge通过为非 id 列创建唯一名称来帮助启动。

    library(data.table) ## for `setnames`
    ## setnames will silently assign new names 
    ##   to the original data in list "y"
    invisible(lapply(seq_along(y), function(z) 
      setnames(y[[z]], "n", paste("n", z, sep = "_"))))
    
  3. 使用“类型”列作为“id”Reducemerge一起列出项目。

    Reduce(function(x, y) merge(x, y, by = "Type", all = TRUE), y)
    #   Type n_1 n_2 n_3 n_4
    # 1    A   1   2   1   8
    # 2    B  20  15   5   9
    # 3    C  34  16   6  NA
    # 4    D   5   5   7  11
    # 5    E  NA  NA  NA   0
    
于 2013-10-08T12:00:48.753 回答
1

在 Python 中,您应该使用它pandas来执行这些操作:

import pandas as pd

df1 = pd.read_csv('1.csv', sep='\s+', index_col=0)
df2 = pd.read_csv('2.csv', sep='\s+', index_col=0)

pd.concat([df1, df2], axis=1)
Out[16]: 
       n   n
Type        
A      1   2
B     20  15
C     34  16
D      5   5

如果您期望更自动的列重命名:

pd.merge(df1, df2, left_index=True, right_index=True, suffixes=['1', '2'])
Out[20]: 
      n1  n2
Type        
A      1   2
B     20  15
C     34  16
D      5   5
于 2013-10-08T11:47:45.813 回答
0

这里的另一个解决方案假设不需要进行合并。例如,如果您有三个文件,则可以像这样读取它们:

n <- 1:3
x <- lapply(sprintf('%s.csv', n), read.csv)

您只想删除每个表中的第一列,以便可以使用sapply()on[[.data.frame删除不需要的列,然后将其全部合并到一个数据框中。

data.frame(Type = x[[1]]$Type, sapply(x, '[[', -1))

或者,如果您真的想要表单中的名称n1n2

data.frame(
  Type = x[[1]]$Type, 
  setNames(lapply(x, '[[', -1), paste0('n', n))
)
于 2013-10-08T12:15:36.657 回答