如何将列附加到列表中的 data.frames,其中该列应包含通过计算读出的那些 data.frames 的结构信息?
How to append a column to data.frames in a list where the column shall contain computationally read out structural information of those data.frames?
我有一些数据在 R 中读取和修改。对于一个最小的、可重现的示例 (reprex),我想将数据作为“在 R 中”的表示来提供,以传达数据结构:
读入数据的代码:
paths <- sprintf("filenames%02d.out", 1:26)
interim <- lapply(paths, read.table, header=FALSE, sep="\t", dec=".", na.strings="NA")
new_col_name <- c("Pos", "LRTD")
out <- lapply(interim, setNames, nm = new_col_name)
现在,lapply(out, head)
允许我们查看数据的 R 内部表示:
[[1]]
Pos LRTD
1 0 0
2 70557 0
3 104076 0
4 163349 0
5 258229 0
6 356613 0
[[2]]
Pos LRTD
1 0 0
2 171603 0
3 268756 0
4 456513 0
5 594904 0
6 663581 0
[[3]]
Pos LRTD
1 0 0.000
2 171960 0.370
3 217096 0.358
4 254484 0.338
5 320866 0.366
6 432642 0.382
{...}
[[26]]
Pos LRTD
1 0 0
2 185161 0
3 234971 0
4 273218 0
5 319689 0
6 379800 0
所以它是一个 list
的 data.frame
具有 26 个元素。在这里,我想把我们在上面看到的数字称为方括号,所以数字 [[1]]
、[[2]]
、[[3]]
等等直到 [[26]]
,作为“元素描述符”。
现在我想做的是将第三列附加到 list
中的所有 data.frame
,其中该列包含通过计算读出的 data.frame
的结构信息.
详细地说,我想将给定 data.frame
的元素描述符添加到它们各自的 data.frame
中。请记住,结果应如下所示:
[[1]]
Pos LRTD Chr
1 0 0 1
2 70557 0 1
[[2]]
Pos LRTD Chr
1 0 0 2
2 171603 0 2
[[3]]
Pos LRTD Chr
1 0 0.000 3
2 171960 0.370 3
{...}
[[26]]
Pos LRTD Chr
1 0 0 26
2 185161 0 26
由于我很清楚这一点,我目前的解决方案是伪代码:
lapply(out, function(x) { x$Chr <- rep("element descriptor","lenght of list");return(x)})
我知道我可以用 rapply(out, length)
得到相应 data.frame
的长度,但到目前为止我还没有得到 rapply
在我的 lapply
中工作来自上方的命令。
还有,如何在代码中引用元素描述符?
Map
很适合这个。
Map(function(x, ind) transform(x, Chr = ind), out, seq_along(out))
# [[1]]
# Pos LRTD Chr
# 1 0 0 1
# 2 70557 0 1
# 3 104076 0 1
# 4 163349 0 1
# 5 258229 0 1
# 6 356613 0 1
# [[2]]
# Pos LRTD Chr
# 1 0 0 2
# 2 171603 0 2
# 3 268756 0 2
# 4 456513 0 2
# 5 594904 0 2
# 6 663581 0 2
# [[3]]
# Pos LRTD Chr
# 1 0 0.000 3
# 2 171960 0.370 3
# 3 217096 0.358 3
# 4 254484 0.338 3
# 5 320866 0.366 3
# 6 432642 0.382 3
# [[4]]
# Pos LRTD Chr
# 1 0 0 4
# 2 185161 0 4
# 3 234971 0 4
# 4 273218 0 4
# 5 319689 0 4
# 6 379800 0 4
如果您的“元素描述符”确实是名称,则将其替换为
Map(function(x, ind) transform(x, Chr = ind), out, names(out))
它会有效地做同样的事情。
如果您对 lapply
感到满意并想知道这与那个的比较,那么 Map
的等效 lapply
将是:
lapply(names(out), function(nm) transform(out[[nm]], Chr = nm))
您甚至可以使用
编写一些代码
Map(transform, out, Chr = seq_along(out))
Map(transform, out, Chr = names(out))
(与上面相同的输出)。这恰好有效,因为我们可以在 Map
中使用命名参数,这些参数传递给 f=
(函数)参数,在本例中为 transform
。
数据:
out <- list(structure(list(Pos = c(0L, 70557L, 104076L, 163349L, 258229L, 356613L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 171603L, 268756L, 456513L, 594904L, 663581L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 171960L, 217096L, 254484L, 320866L, 432642L), LRTD = c(0, 0.37, 0.358, 0.338, 0.366, 0.382)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 185161L, 234971L, 273218L, 319689L, 379800L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")))
涉及 purrr
的一个选项可能是:
imap(out, ~ update_list(.x, Chr = .y))
[[1]]
Pos LRTD Chr
1 0 0 1
2 70557 0 1
3 104076 0 1
4 163349 0 1
5 258229 0 1
6 356613 0 1
[[2]]
Pos LRTD Chr
1 0 0 2
2 171603 0 2
3 268756 0 2
4 456513 0 2
5 594904 0 2
6 663581 0 2
[[3]]
Pos LRTD Chr
1 0 0.000 3
2 171960 0.370 3
3 217096 0.358 3
4 254484 0.338 3
5 320866 0.366 3
6 432642 0.382 3
[[4]]
Pos LRTD Chr
1 0 0 4
2 185161 0 4
3 234971 0 4
4 273218 0 4
5 319689 0 4
6 379800 0 4
显然,所有文件都具有相似的结构,即列的顺序和类型相同(名称可能不同)。因此,我希望您不要介意我提出一种完全不同的方法,它不能回答您的实际问题,但可能有助于解决我认为是潜在问题的问题。
在这种情况下,我的首选方法是将所有文件合并到一个大型数据集中,其中在 id 列中为每一行指示来源(OP 元素描述符 Chr
).
所以,这是我使用我喜欢的工具集会做的事情
library(data.table)
library(magrittr)
new_col_name <- c("Pos", "LRTD")
paths <- sprintf("filenames%02d.out", 1:26)
out <- lapply(paths, read.table, header=FALSE, sep="\t", dec=".", na.strings="NA") %>%
rbindlist(use.names = FALSE, idcol = "Chr") %>%
setnames(old = 2:3, new = new_col_name)
Chr Pos LRTD
1: 1 0 0.000
2: 1 70557 0.000
3: 1 104076 0.000
4: 1 163349 0.000
5: 1 258229 0.000
6: 1 356613 0.000
7: 2 0 0.000
8: 2 171603 0.000
9: 2 268756 0.000
10: 2 456513 0.000
11: 2 594904 0.000
12: 2 663581 0.000
13: 3 0 0.000
14: 3 171960 0.370
15: 3 217096 0.358
16: 3 254484 0.338
17: 3 320866 0.366
18: 3 432642 0.382
19: 4 0 0.000
20: 4 185161 0.000
21: 4 234971 0.000
22: 4 273218 0.000
23: 4 319689 0.000
24: 4 379800 0.000
Chr Pos LRTD
因此,对于一个大型数据集中的所有数据,我们可以对整列进行操作,而无需调用 lapply()
来处理每个块,但我们可以按 Chr
分组或子集,如果必要的。这种方法在很多情况下简化了我的工作流程。
我有一些数据在 R 中读取和修改。对于一个最小的、可重现的示例 (reprex),我想将数据作为“在 R 中”的表示来提供,以传达数据结构:
读入数据的代码:
paths <- sprintf("filenames%02d.out", 1:26)
interim <- lapply(paths, read.table, header=FALSE, sep="\t", dec=".", na.strings="NA")
new_col_name <- c("Pos", "LRTD")
out <- lapply(interim, setNames, nm = new_col_name)
现在,lapply(out, head)
允许我们查看数据的 R 内部表示:
[[1]]
Pos LRTD
1 0 0
2 70557 0
3 104076 0
4 163349 0
5 258229 0
6 356613 0
[[2]]
Pos LRTD
1 0 0
2 171603 0
3 268756 0
4 456513 0
5 594904 0
6 663581 0
[[3]]
Pos LRTD
1 0 0.000
2 171960 0.370
3 217096 0.358
4 254484 0.338
5 320866 0.366
6 432642 0.382
{...}
[[26]]
Pos LRTD
1 0 0
2 185161 0
3 234971 0
4 273218 0
5 319689 0
6 379800 0
所以它是一个 list
的 data.frame
具有 26 个元素。在这里,我想把我们在上面看到的数字称为方括号,所以数字 [[1]]
、[[2]]
、[[3]]
等等直到 [[26]]
,作为“元素描述符”。
现在我想做的是将第三列附加到 list
中的所有 data.frame
,其中该列包含通过计算读出的 data.frame
的结构信息.
详细地说,我想将给定 data.frame
的元素描述符添加到它们各自的 data.frame
中。请记住,结果应如下所示:
[[1]]
Pos LRTD Chr
1 0 0 1
2 70557 0 1
[[2]]
Pos LRTD Chr
1 0 0 2
2 171603 0 2
[[3]]
Pos LRTD Chr
1 0 0.000 3
2 171960 0.370 3
{...}
[[26]]
Pos LRTD Chr
1 0 0 26
2 185161 0 26
由于我很清楚这一点
lapply(out, function(x) { x$Chr <- rep("element descriptor","lenght of list");return(x)})
我知道我可以用 rapply(out, length)
得到相应 data.frame
的长度,但到目前为止我还没有得到 rapply
在我的 lapply
中工作来自上方的命令。
还有,如何在代码中引用元素描述符?
Map
很适合这个。
Map(function(x, ind) transform(x, Chr = ind), out, seq_along(out))
# [[1]]
# Pos LRTD Chr
# 1 0 0 1
# 2 70557 0 1
# 3 104076 0 1
# 4 163349 0 1
# 5 258229 0 1
# 6 356613 0 1
# [[2]]
# Pos LRTD Chr
# 1 0 0 2
# 2 171603 0 2
# 3 268756 0 2
# 4 456513 0 2
# 5 594904 0 2
# 6 663581 0 2
# [[3]]
# Pos LRTD Chr
# 1 0 0.000 3
# 2 171960 0.370 3
# 3 217096 0.358 3
# 4 254484 0.338 3
# 5 320866 0.366 3
# 6 432642 0.382 3
# [[4]]
# Pos LRTD Chr
# 1 0 0 4
# 2 185161 0 4
# 3 234971 0 4
# 4 273218 0 4
# 5 319689 0 4
# 6 379800 0 4
如果您的“元素描述符”确实是名称,则将其替换为
Map(function(x, ind) transform(x, Chr = ind), out, names(out))
它会有效地做同样的事情。
如果您对 lapply
感到满意并想知道这与那个的比较,那么 Map
的等效 lapply
将是:
lapply(names(out), function(nm) transform(out[[nm]], Chr = nm))
您甚至可以使用
编写一些代码Map(transform, out, Chr = seq_along(out))
Map(transform, out, Chr = names(out))
(与上面相同的输出)。这恰好有效,因为我们可以在 Map
中使用命名参数,这些参数传递给 f=
(函数)参数,在本例中为 transform
。
数据:
out <- list(structure(list(Pos = c(0L, 70557L, 104076L, 163349L, 258229L, 356613L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 171603L, 268756L, 456513L, 594904L, 663581L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 171960L, 217096L, 254484L, 320866L, 432642L), LRTD = c(0, 0.37, 0.358, 0.338, 0.366, 0.382)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")), structure(list(Pos = c(0L, 185161L, 234971L, 273218L, 319689L, 379800L), LRTD = c(0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6")))
涉及 purrr
的一个选项可能是:
imap(out, ~ update_list(.x, Chr = .y))
[[1]]
Pos LRTD Chr
1 0 0 1
2 70557 0 1
3 104076 0 1
4 163349 0 1
5 258229 0 1
6 356613 0 1
[[2]]
Pos LRTD Chr
1 0 0 2
2 171603 0 2
3 268756 0 2
4 456513 0 2
5 594904 0 2
6 663581 0 2
[[3]]
Pos LRTD Chr
1 0 0.000 3
2 171960 0.370 3
3 217096 0.358 3
4 254484 0.338 3
5 320866 0.366 3
6 432642 0.382 3
[[4]]
Pos LRTD Chr
1 0 0 4
2 185161 0 4
3 234971 0 4
4 273218 0 4
5 319689 0 4
6 379800 0 4
显然,所有文件都具有相似的结构,即列的顺序和类型相同(名称可能不同)。因此,我希望您不要介意我提出一种完全不同的方法,它不能回答您的实际问题,但可能有助于解决我认为是潜在问题的问题。
在这种情况下,我的首选方法是将所有文件合并到一个大型数据集中,其中在 id 列中为每一行指示来源(OP 元素描述符 Chr
).
所以,这是我使用我喜欢的工具集会做的事情
library(data.table)
library(magrittr)
new_col_name <- c("Pos", "LRTD")
paths <- sprintf("filenames%02d.out", 1:26)
out <- lapply(paths, read.table, header=FALSE, sep="\t", dec=".", na.strings="NA") %>%
rbindlist(use.names = FALSE, idcol = "Chr") %>%
setnames(old = 2:3, new = new_col_name)
Chr Pos LRTD 1: 1 0 0.000 2: 1 70557 0.000 3: 1 104076 0.000 4: 1 163349 0.000 5: 1 258229 0.000 6: 1 356613 0.000 7: 2 0 0.000 8: 2 171603 0.000 9: 2 268756 0.000 10: 2 456513 0.000 11: 2 594904 0.000 12: 2 663581 0.000 13: 3 0 0.000 14: 3 171960 0.370 15: 3 217096 0.358 16: 3 254484 0.338 17: 3 320866 0.366 18: 3 432642 0.382 19: 4 0 0.000 20: 4 185161 0.000 21: 4 234971 0.000 22: 4 273218 0.000 23: 4 319689 0.000 24: 4 379800 0.000 Chr Pos LRTD
因此,对于一个大型数据集中的所有数据,我们可以对整列进行操作,而无需调用 lapply()
来处理每个块,但我们可以按 Chr
分组或子集,如果必要的。这种方法在很多情况下简化了我的工作流程。