我有一个看起来像这样的大data.frame:
Statistic1 fdr1 Value1 Statistic2 fdr2 Value2
2 0.0001 Signif 1.8 0.001 Signif
0.3 0.13 0 5 0.5 0
1.5 0.01 Signif 0.4 0.009 Signif
我想每3列拆分一次数据帧,例如Statistic1,fdr1和Value1。然后按Statistic *列按降序对每个拆分的data.frame进行排序,并获取与Value *列中的Signif标签对应的每个已排序data.frames的前20行名称。 排序后的data.frame。
所需的输出
> df1
> Statistic1 fdr1 Value1
> 2 0.0001 Signif
> 1.5 0.01 Signif
> Statistic2 fdr2 Value2
> 1.8 0.001 Signif
> 0.4 0.009 Signif
从每个单个data.frame中,我将获取前20行名称。
有人可以帮我吗?
答案 0 :(得分:3)
您可以使用split.default
分割数据帧。遍历列表并执行所需的操作。翻译您的要求会给您
lapply(split.default(df, gsub('\\D+', '', names(df))), function(i)
{i <- i[i[3] != 0,];
i <- i[order(i[1], decreasing = TRUE),];
i[1:20,]})
但是,请注意,由于您的示例只有3行,因此执行最后一个条件(1:20
)将导致NA
行
答案 1 :(得分:1)
这是基于this answers的另一个基本解决方案,它将数据集每三列拆分一次,而不会看到名称:
lapply(seq(1, ncol(df), by=3), function(i) {
i <- df[i: pmin((i+2), ncol(df))]
i <- i[order(i[1], decreasing = TRUE),]
head(i,2) # put 2 to see the results, you need 20
})
[[1]]
Statistic1 fdr1 Value1
1 2.0 0.001 Signif
3 1.5 0.010 Signif
[[2]]
Statistic2 fdr2 Value2
2 5.0 0.500 0
1 1.8 0.001 Signif
使用伪造数据:
df <- data.frame(Statistic1 = c(2, 0.3, 1.5),
fdr1 = c(0.001, 0.13, 0.01),
Value1 = c("Signif",0,"Signif"),
Statistic2 = c(1.8,5,0.4),
fdr2 = c(0.001, 0.5, 0.009),
Value2 = c("Signif",0,"Signif"),
stringsAsFactors = FALSE)
答案 2 :(得分:0)
tidyverse
使用基数R split.default
的答案,我们每隔3列进行拆分,根据第一列拆分arrange
,从第三列拆分filter
值,最后选择行。
library(tidyverse)
map(split.default(df, gl(ncol(df)/3, 3)),
. %>% arrange_at(1) %>%
filter_at(3, ~. != 0) %>%
slice(n() : (n()- 2)))
#$`1`
# Statistic1 fdr1 Value1
#1 2.0 0.0001 Signif
#2 1.5 0.0100 Signif
#$`2`
# Statistic2 fdr2 Value2
#1 1.8 0.001 Signif
#2 0.4 0.009 Signif
在此示例中,仅选择2行,对于实际数据,您可以将2更改为20以获取前20行。