我有一个程序可以根据列上的条件列表从数据框中提取项目(请参阅使用 (column_name = value) 列表给出的条件从 R 数据框中提取项目):
以下是数据框和条件列表:
> experimental_plan_1
lib genotype treatment replicate
1 A WT normal 1
2 B WT hot 1
3 C mut normal 1
4 D mut hot 1
5 E WT normal 2
6 F WT hot 2
7 G mut normal 2
8 H mut hot 2
> condition_1 <- list(genotype="WT", treatment="normal")
我的目标是提取与lib
列表中给出的标准相对应的行的列中的值。
我可以使用以下函数来提取想要的值:
> get_libs <- function(experimental_plan, condition) {experimental_plan[apply((experimental_plan[, names(condition)] == condition), 1, all), "lib"]}
这适用于上述数据框:
> get_libs(experimental_plan_1, condition_1)
[1] A E
Levels: A B C D E F G H
但是,我希望这个更笼统:我的experimental_plan
和condition
可以有不同的列:
> experimental_plan_2
lib genotype replicate
1 A WT 1
2 B WT 2
3 C WT 3
4 D mut 1
5 E mut 2
6 F mut 3
> condition_2 <- list(genotype="WT")
这次失败了:
> get_libs(experimental_plan_2, condition_2)
Error in apply((experimental_plan[, names(condition)] == condition), 1, :
dim(X) must have a positive length
在这种情况下,预期的输出应该是:
[1] A B C
Levels: A B C D E F
如何编写一个以更健壮的方式执行相同操作的函数?
评论
尽管两种情况非常相似,但我发现该函数不起作用,这让我感到非常沮丧:两个数据框都有一个lib
列,并且在这两种情况下,条件列表中的名称都对应于数据框中的列名。
当从数据框中提取的列数减少到一时,R 显然会自动将 data.frame 转换为因子:
> class(experimental_plan_1)
[1] "data.frame"
> class(experimental_plan_2)
[1] "data.frame"
> class(names(condition_1))
[1] "character"
> class(names(condition_2))
[1] "character"
> class(experimental_plan_1[, names(condition_1)])
[1] "data.frame"
> class(experimental_plan_2[, names(condition_2)])
[1] "factor"
这违背了最小意外原则。当给定相同类型的输入时,我希望计算返回相同类型的输出。