我在列表中有28个列表,我尝试将另一个名为ID的变量添加到每个列表中。我发现这个Dataframes in a list; adding a new variable with name of dataframe非常有帮助。但是当我尝试他的代码时,它在我的情况下不起作用。我认为这是因为我的列表没有明确的标签[1],[2]。[3]等等,代码可以识别。
all$id <- rep(names(mylist), sapply(mylist, nrow))
>List of 1
$ :List of 28
..$ :'data.frame': 271 obs. of 12 variables:
.. ..$ Sample_ID : Factor w/ 271 levels "MC25",..: 19 27 2
.. ..$ Reported_Analyte : Factor w/ 10 levels "2-Butoxyethanol",..: 7 7 7
..$ Date_Collected : Factor w/ 71 levels "2010-05-08","2010-05-09",..: 8 9 1
.. ..$ Result2 : num [1:271] 0.11 0.11 0.11 0.11
..$ :'data.frame': 6 obs. of 12 variables:
.. ..$ Sample_ID : Factor w/ 271 levels "MC25",..: 19 27 2
.. ..$ Reported_Analyte : Factor w/ 10 levels "2-Butoxyethanol",..: 7 7 7
..$ Date_Collected : Factor w/ 71 levels "2010-05-08","2010-05-09",..: 8 9 1
.. ..$ Result2 : num [1:271] 0.11 0.11 0.11 0.11
答案 0 :(得分:3)
我使用带有mtcars
的样本的列表的构造示例来回答这个问题。
首先,创建一个数据框列表。通过从mtcars
为列表的每个元素抽取10行来执行此操作:
ml <- lapply(1:3, function(x)mtcars[sample(1:32, 10), 1:3])
所以,现在你有一个3个数据框的未命名列表。接下来,您要添加id
列。诀窍是使用lapply
对一系列列表项使用seq_along(ml)
,然后将cbind
个ID用于每个数据框:
ml2 <- lapply(seq_along(ml), function(x)cbind(ml[[x]], id=x))
结果是您所需要的:
str(ml2)
List of 3
$ :'data.frame': 10 obs. of 4 variables:
..$ mpg : num [1:10] 15 24.4 26 15.8 22.8 21 32.4 17.3 17.8 30.4
..$ cyl : num [1:10] 8 4 4 8 4 6 4 8 6 4
..$ disp: num [1:10] 301 147 120 351 108 ...
..$ id : int [1:10] 1 1 1 1 1 1 1 1 1 1
$ :'data.frame': 10 obs. of 4 variables:
..$ mpg : num [1:10] 33.9 19.2 24.4 10.4 30.4 22.8 16.4 21.4 15.5 21.5
..$ cyl : num [1:10] 4 6 4 8 4 4 8 6 8 4
..$ disp: num [1:10] 71.1 167.6 146.7 460 75.7 ...
..$ id : int [1:10] 2 2 2 2 2 2 2 2 2 2
$ :'data.frame': 10 obs. of 4 variables:
..$ mpg : num [1:10] 15.5 21 13.3 21.5 21.4 30.4 21 18.1 30.4 15.2
..$ cyl : num [1:10] 8 6 8 4 4 4 6 6 4 8
..$ disp: num [1:10] 318 160 350 120 121 ...
..$ id : int [1:10] 3 3 3 3 3 3 3 3 3 3
答案 1 :(得分:3)
目前还不是很清楚你要实现的目标(链接的帖子是关于折叠数据框列表并在折叠版本中添加一个ID变量,指示折叠数据中每行的原始数据框)框架来自)。
我发现你的数据很复杂;你有一个列表中的28个数据框 列表。您可以在Q中给出str()
的输出中看到这一点。您可以通过此示例数据集更好地看到这一点(此处所有数据框都相同,但这只是为了方便)
set.seed(42)
dat <- data.frame(Sample_ID = factor(sample(10)),
Reported_Analyte = factor(sample(LETTERS, 10)),
Date_Collected = Sys.Date() + 0:9,
Result2 = rnorm(10))
mylist <- list(lapply(1:28, function(x) dat))
如果我们使用mylist
查看str()
,我们会看到我提到的并发症的性质:
R> str(mylist, max = 2)
List of 1
$ :List of 28
..$ Data_frame_ 1 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 2 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 3 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 4 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 5 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 6 :'data.frame': 10 obs. of 4 variables:
..$ Data_frame_ 7 :'data.frame': 10 obs. of 4 variables:
....<etc>
您链接到的帖子的起始位置是里面您的外部列表中的列表,并且该列表已命名组件。如果您不需要外部列表,也许最好在此阶段将其丢弃:
mylist2 <- mylist[[1]]
## the `[[` are important as we want the 1st component *inside* the list
## using `[` would just give us a list within a list again.
然后可以将名称添加到此列表
names(mylist2) <- paste("Data_frame_", seq_along(mylist2), sep = "")
会导致
R> str(mylist2)
List of 28
$ Data_frame_1 :'data.frame': 10 obs. of 4 variables:
..$ Sample_ID : Factor w/ 10 levels "1","2","3","4",..: 10 9 3 6 4 8 5 1 2 7
..$ Reported_Analyte: Factor w/ 10 levels "C","F","I","J",..: 6 7 10 2 5 8 9 1 3 4
..$ Date_Collected : Date[1:10], format: "2012-05-02" "2012-05-03" ...
..$ Result2 : num [1:10] 1.305 2.287 -1.389 -0.279 -0.133 ...
$ Data_frame_2 :'data.frame': 10 obs. of 4 variables:
..$ Sample_ID : Factor w/ 10 levels "1","2","3","4",..: 10 9 3 6 4 8 5 1 2 7
..$ Reported_Analyte: Factor w/ 10 levels "C","F","I","J",..: 6 7 10 2 5 8 9 1 3 4
..$ Date_Collected : Date[1:10], format: "2012-05-02" "2012-05-03" ...
..$ Result2 : num [1:10] 1.305 2.287 -1.389 -0.279 -0.133 ...
....<etc>
请注意,不再报告List of 1
。
如果列表中的数据框列表对您很重要(不确定为什么会这样,但可以),那么您可以直接将名称分配给[[1]]
st组件。
names(mylist[[1]]) <- paste("Data_frame_", seq_along(mylist[[1]]), sep = "")
(注意我使用原始mylist
,并且在两种情况下我都使用[[1]]
索引该列表。)
虽然保留了列表结构中的列表,但结果类似于上面的结果:
R> str(mylist)
List of 1
$ :List of 28
..$ Data_frame_1 :'data.frame': 10 obs. of 4 variables:
.. ..$ Sample_ID : Factor w/ 10 levels "1","2","3","4",..: 10 9 3 6 4 8 5 1 2 7
.. ..$ Reported_Analyte: Factor w/ 10 levels "C","F","I","J",..: 6 7 10 2 5 8 9 1 3 4
.. ..$ Date_Collected : Date[1:10], format: "2012-05-02" "2012-05-03" ...
.. ..$ Result2 : num [1:10] 1.305 2.287 -1.389 -0.279 -0.133 ...
..$ Data_frame_2 :'data.frame': 10 obs. of 4 variables:
.. ..$ Sample_ID : Factor w/ 10 levels "1","2","3","4",..: 10 9 3 6 4 8 5 1 2 7
.. ..$ Reported_Analyte: Factor w/ 10 levels "C","F","I","J",..: 6 7 10 2 5 8 9 1 3 4
.. ..$ Date_Collected : Date[1:10], format: "2012-05-02" "2012-05-03" ...
.. ..$ Result2 : num [1:10] 1.305 2.287 -1.389 -0.279 -0.133 ...
....<etc>
如果您现在希望继续将各个数据框折叠到一个数据框中,但保留有关它们来自哪个数据框的信息,我们会针对mylist2
执行此操作:
all2 <- do.call("rbind", mylist2)
all2 <- transform(all2, id = rep(names(mylist2), sapply(mylist2, nrow)))
rownames(all2) <- seq_len(nrow(all2)) ## reset rownames for compactness
给出:
R> head(all2)
Sample_ID Reported_Analyte Date_Collected Result2 id
1 10 L 2012-05-02 1.3048697 Data_frame_1
2 9 R 2012-05-03 2.2866454 Data_frame_1
3 3 W 2012-05-04 -1.3888607 Data_frame_1
4 6 F 2012-05-05 -0.2787888 Data_frame_1
5 4 K 2012-05-06 -0.1333213 Data_frame_1
6 8 T 2012-05-07 0.6359504 Data_frame_1
对于mylist
,我们使用非常相似的内容,但只使用mylist
索引[[1]]
:
all1 <- do.call("rbind", mylist[[1]])
all1 <- transform(all1, id = rep(names(mylist[[1]]), sapply(mylist[[1]], nrow)))
rownames(all1) <- seq_len(nrow(all1)) ## reset rownames for compactness
R> head(all1)
Sample_ID Reported_Analyte Date_Collected Result2 id
1 10 L 2012-05-02 1.3048697 Data_frame_1
2 9 R 2012-05-03 2.2866454 Data_frame_1
3 3 W 2012-05-04 -1.3888607 Data_frame_1
4 6 F 2012-05-05 -0.2787888 Data_frame_1
5 4 K 2012-05-06 -0.1333213 Data_frame_1
6 8 T 2012-05-07 0.6359504 Data_frame_1
正如您所看到的那样,如果您不需要外部列表,则需要反复引用数据框列表为mylist[[1]]
。
<强>更新强>
如果您不想将列表折叠为单个数据框,请参阅@Andrie的答案,但将其修改为:
ml2 <- ml1
ml2[[1]] <- lapply(seq_along(ml[[1]]), function(x)cbind(ml[[1]][[x]], id=x))
所以你考虑了列表结构中的列表。