我更喜欢在R中执行以下操作,但我愿意(易于学习)其他解决方案。
我有多个(比方说99个)制表符分隔的文件(让我们通过S99.txt称它们为S1.txt)和表格,所有这些都具有完全相同的格式。每张表约为2,000,000列,每行5行。这是一个玩具示例:
ID Chr Position DP1 DP2
A1 1 123 1.5 2.0
A2 1 124 1.4 0.3
ID根据定义是唯一的,并且总是以相同的顺序,Chr和Pos总是以相同的顺序。每个输入文件中唯一不同的是DP1列和DP2列。输出表我喜欢"整理",我认为就是这个词。如果只有3个Sample输入文件,那么这是一个输出示例。
ID Chr Position S1.DP1 S1.DP2 S2.DP1 S2.DP2 S3.DP1 S3.DP2
A1 1 123 1.5 2.0 1.2 2.0 1.5 2.1
A2 1 124 1.4 0.3 1.0 0.5 0.5 0.05
请注意,每个输入文件都有为DP1和DP2创建的新列。此外,列的名称是提供信息的(告诉我它来自哪个输入文件&哪个数据点-DP)。
我发现了有关列不同时的问题: R: merging a lot of data.frames 我也知道合并,虽然我觉得你最终得到了奇怪的列名: How to join (merge) data frames (inner, outer, left, right)?
我的另一个解决方案是初始化一个数据帧,然后加载每个文件并添加数据点,但这将使用一个循环,并且非常慢和可怕。 所以,我需要一个更优雅的解决方案。谢谢你的帮助。
答案 0 :(得分:2)
我将假设所有文件都存储在一个文件夹中,并且您要加载该文件夹中包含## List all the files in the current directory that end in .txt
files <- list.files(path = ".", pattern = "*.txt")
## Load them into a list called datlist and name each element after the file it came from
datlist <- lapply(files, read.table, sep = "\t")
names(datlist) <- gsub("(*).txt", "\\1", files)
个扩展名的所有文件。
S1 <- read.table(text = "ID Chr Position DP1 DP2
A1 1 123 1.5 2.0
A2 1 124 1.4 0.3", header = TRUE)
S2 <- read.table(text = "ID Chr Position DP1 DP2
A1 1 123 1.2 2.0
A2 1 124 1.0 0.5", header = TRUE)
S3 <- read.table(text = "ID Chr Position DP1 DP2
A1 1 123 1.5 2.1
A2 1 124 0.5 0.05", header = TRUE)
datlist <- list(S1 = S1, S2 = S2, S3 = S3)
然而,出于可重现的例子的目的,我将手动创建一个数据框列表,如您所展示的那样。
library("dplyr")
library("tidyr")
现在加载我们将要使用的软件包
## First, combine the list into a single data frame, adding a column to indicate
## which file each row came from
bind_rows(datlist, .id = "file") %>%
## Gather this into a longer format with DP1/DP2 as variables
gather(key = col, value = value, which(!names(.) %in% c("ID", "Chr", "Position", "file"))) %>%
## Create a new column that combines the file name and DP1/DP2 -- this will be
## the final column names
unite(newcol, file, col, sep = ".") %>%
## Spread the data so that each combination of file and DP1/DP2 is its own
## column
spread(newcol, value)
通过混合使用dplyr和tidyr函数,我们可以得到您想要的结果:
## Source: local data frame [2 x 9]
## ID Chr Position S1.DP1 S1.DP2 S2.DP1 S2.DP2 S3.DP1 S3.DP2
## (fctr) (int) (int) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
## 1 A1 1 123 1.5 2.0 1.2 2.0 1.5 2.10
## 2 A2 1 124 1.4 0.3 1.0 0.5 0.5 0.05
最终结果:
<?php
require_once realpath(dirname(__FILE__).'/google-api-php-client/autoload.php');
$client_email = '1234567890-a1b2c3d4e5f6g7h8i@developer.gserviceaccount.com';
$private_key = file_get_contents('MyProject.p12');
$scopes = array('https://www.googleapis.com/auth/sqlservice.admin');
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$sqladmin = new Google_Service_SQLAdmin($client);
$response = $sqladmin->instances
->listInstances('examinable-example-123')->getItems();
echo json_encode($response) . "\n";
答案 1 :(得分:2)
我重新阅读了你的问题并想到了一个更好的解决方案。
首先,我不会立即将所有.txt文件加载到R中。如果您的.txt文件是2e6x5并且有100个文件,则在加载它们之前可能会耗尽RAM。我会一次加载一个并迭代合并它们。
library(readr) #Use this to load your data, it is much better than the base functions
f <- list.files(path = "path/to/file", pattern = "*.txt", full.names = TRUE)
d <- read_delim(f[1], delim = "\t")
idx = c("ID", "Chr", "Position")
for (i in seq(2, length(f)){
d_temp <- read_delim(f[i], delim = "\t")
d <- merge(d, d_temp, by = idx)
rm(d_temp) #not necessary but I like to include to make explicit
}
命名d
n <- expand.grid(paste0("S", seq(1, length(f)), c("DP1", "DP2"))
names(d)[!names(d) %in% idx] <- paste(n[ ,1], n[ ,2], sep = ".")
<强>更新强>
呃我错过了显而易见的,如果你真的有100个2e6x5 .txt文件,你可能无法使用R来执行此任务。我怀疑是否有可能在R中存储一个2e6X500数据帧。即使你在服务器上有大量的RAM计算时间也是非常重要的。我认为最重要的问题是你要对这些数据做些什么。一旦你回答这个问题,你就可以有效地使用你的数据。
答案 2 :(得分:1)
具有碱基R的单衬里
l = list(S1=S1, S2=S2, S3=S3)
idx = c("ID","Chr","Position")
d <- Reduce(function(x, y) merge(x, y, by = idx), l)
<强>更新强>
忘记变量名称。这可能有点过分,但这是我能想到的最好的方法,以避免对名称进行硬编码。
n <- expand.grid(names(l), setdiff(names(S1), idx))
names(d)[!names(d)%in%idx] <- paste(n[ ,1], n[ ,2], sep = ".")