使用嵌套 for 循环生成的唯一组合创建数据框
Create a data frame with unique combo generated from nested for loops
我有这样一个数据框:
Feature ID Sub Value
1 A T1 B1 5.87
2 B T1 B2 3.99
3 C T1 B3 12.57
4 A T1 B2 9.22
5 B T1 B3 7.89
6 C T1 B1 4.76
7 A T2 B1 4.56
8 B T2 B2 9.26
9 C T2 B2 7.44
我想做的是 运行 这个数据集中的一个因子方差分析,因子是“子”。我想循环遍历每个功能并循环遍历每个 ID。基本上,我正在计算一个 ID 内每个特征在“Sub”之间的方差。
我已经生成了下面的代码,但它似乎不起作用。
datalist <- list()
for (i in unique(data1$Feature)) {
for (j in unique(data1$ID)) {
A1 <- summary(aov(data1$value ~ as.factor(data1$Sub), data=data1))
datalist[[j]] <- A1
}
}
big_data <- do.call(rbind, datalist)
我最终得到 big_data,这是一个包含 36 个列表的矩阵。我无法访问 Anova 输出。它不一定是数据框。即使它是循环中的“write.csv()”也会生成不同的输出。最终,我只需要 Anova 输出的“between”因子参数来生成一个图,所以如果这也可以合并到代码中,那将大有帮助。
当前设置的几个问题:
您实际上并没有在 anova
调用中使用 i
和 j
,因此所有嵌套的 for
循环迭代将 return 在整个数据帧上得到完全相同的结果 运行。快速修复:subset
数据框由第 i 个和第 j 个值组成。
anova(value ~ Sub, data = subset(data1, Feature == i & ID == j))
您仅在 j
值下保存列表元素而不是 i
和 j
,因此迭代将重复重新分配并且仅保存 最后 遍 j
项。快速修复:添加第 i 个和第 j 个值的命名元素。
datalist[[paste0(i, "_", j)]] <- A1
您正在尝试 rbind
列出对象,而不是矩阵或数据框,因为 summary.anova
return 是结果列表。对于您的用例,调用 str
显示您的结果包含 1:
的列表
str(summary(aov(data1$value ~ as.factor(data1$Sub), data = data1)))
List of 1
$ :Classes ‘anova’ and 'data.frame': 2 obs. of 5 variables:
..$ Df : num [1:2] ...
..$ Sum Sq : num [1:2] ...
..$ Mean Sq: num [1:2] ...
..$ F value: num [1:2] ...
..$ Pr(>F) : num [1:2] ...
- attr(*, "class")= chr [1:2] "summary.aov" "listof"
快速修复:索引第一项。
summary(anova(...))[[1]]
但是,考虑 apply 家庭解决方案 by
(tapply
的面向对象包装器)并避免初始化列表的簿记和迭代分配在嵌套的 for
循环中。具体来说,by
可以将数据帧拆分为一个或多个组,并对子集进行 运行 操作以 return 一个列表,该列表等于组的所有可能唯一值。另外,考虑使用定义的方法来封装每个子集上的所有处理。
# USER-DEFINED METHOD
run_anova <- function(sub_df) {
# RAW RESULTS
anova_raw <- summary(aov(value ~ Sub, data = sub_df))[[1]]
# CLEAN UP DATA WITH IDENTIFIERS
anova_df <- data.frame(
within(anova_raw, {Feature <- sub_df$Feature[1]; ID <- sub_df$ID[1]}),
row.names = NULL,
check.names = FALSE
)
return(anova_df)
}
datalist <- by(data1, data1[c("Feature", "ID")], run_anova)
big_data <- do.call(rbind, unname(datalist))
我有这样一个数据框:
Feature ID Sub Value
1 A T1 B1 5.87
2 B T1 B2 3.99
3 C T1 B3 12.57
4 A T1 B2 9.22
5 B T1 B3 7.89
6 C T1 B1 4.76
7 A T2 B1 4.56
8 B T2 B2 9.26
9 C T2 B2 7.44
我想做的是 运行 这个数据集中的一个因子方差分析,因子是“子”。我想循环遍历每个功能并循环遍历每个 ID。基本上,我正在计算一个 ID 内每个特征在“Sub”之间的方差。
我已经生成了下面的代码,但它似乎不起作用。
datalist <- list()
for (i in unique(data1$Feature)) {
for (j in unique(data1$ID)) {
A1 <- summary(aov(data1$value ~ as.factor(data1$Sub), data=data1))
datalist[[j]] <- A1
}
}
big_data <- do.call(rbind, datalist)
我最终得到 big_data,这是一个包含 36 个列表的矩阵。我无法访问 Anova 输出。它不一定是数据框。即使它是循环中的“write.csv()”也会生成不同的输出。最终,我只需要 Anova 输出的“between”因子参数来生成一个图,所以如果这也可以合并到代码中,那将大有帮助。
当前设置的几个问题:
您实际上并没有在
anova
调用中使用i
和j
,因此所有嵌套的for
循环迭代将 return 在整个数据帧上得到完全相同的结果 运行。快速修复:subset
数据框由第 i 个和第 j 个值组成。anova(value ~ Sub, data = subset(data1, Feature == i & ID == j))
您仅在
j
值下保存列表元素而不是i
和j
,因此迭代将重复重新分配并且仅保存 最后 遍j
项。快速修复:添加第 i 个和第 j 个值的命名元素。datalist[[paste0(i, "_", j)]] <- A1
您正在尝试
的列表rbind
列出对象,而不是矩阵或数据框,因为summary.anova
return 是结果列表。对于您的用例,调用str
显示您的结果包含 1:str(summary(aov(data1$value ~ as.factor(data1$Sub), data = data1))) List of 1 $ :Classes ‘anova’ and 'data.frame': 2 obs. of 5 variables: ..$ Df : num [1:2] ... ..$ Sum Sq : num [1:2] ... ..$ Mean Sq: num [1:2] ... ..$ F value: num [1:2] ... ..$ Pr(>F) : num [1:2] ... - attr(*, "class")= chr [1:2] "summary.aov" "listof"
快速修复:索引第一项。
summary(anova(...))[[1]]
但是,考虑 apply 家庭解决方案 by
(tapply
的面向对象包装器)并避免初始化列表的簿记和迭代分配在嵌套的 for
循环中。具体来说,by
可以将数据帧拆分为一个或多个组,并对子集进行 运行 操作以 return 一个列表,该列表等于组的所有可能唯一值。另外,考虑使用定义的方法来封装每个子集上的所有处理。
# USER-DEFINED METHOD
run_anova <- function(sub_df) {
# RAW RESULTS
anova_raw <- summary(aov(value ~ Sub, data = sub_df))[[1]]
# CLEAN UP DATA WITH IDENTIFIERS
anova_df <- data.frame(
within(anova_raw, {Feature <- sub_df$Feature[1]; ID <- sub_df$ID[1]}),
row.names = NULL,
check.names = FALSE
)
return(anova_df)
}
datalist <- by(data1, data1[c("Feature", "ID")], run_anova)
big_data <- do.call(rbind, unname(datalist))