如何使用 R 根据条件识别多列的频率
How to identify frequencies of multiple columns based on condition using R
我有一个包含 63 列和 50 行的数据框。我在下面给出了一个玩具数据集。
>df
rs_1 rs_2 rs_3 rs_4 ... rs_60 A.Ag B.Ag C.Ag
0 0 1 2 ... 1 02:/01 02:/07 03:07/04:01
1 2 1 2 ... 0 02:/01 02:/07 03:07/04:01
2 1 1 2 ... 2 02:/01 02:/07 03:07/04:01
0 0 1 0 ... 2 02:/01 02:/07 03:07/04:01
现在我需要分别为每个 rs_* =0、1 和 2 找到列(A.Ag、B.Ag 和 C.Ag)的最高频率。期望的结果是例如 rs_*=0
rs_id Code A.Ag Code B.Ag Code C.Ag
rs_1 02:/01 2 02:/07 5 03:07 5
rs_2 02:/01 3 01:/05 2 05:00 4
你能帮我解决这个问题吗?我尝试了以下功能
for (i in 1:60){
if (file[,i]==0)
{
temp1 = data.frame(sort(table(file[,61]), decreasing = TRUE)) #onlr for A.Ag coulmn
temp1$Var1 = names(file)[i]
res_types = rbind(res_types, temp1)
}
}
我得到了频率数和rs_id。但是无法获取代码。谁能帮我解决这个问题?
希望的结果是
rs_id Code Combination A.A Combination B.Ag Combination C.Ag
rs_1 0 1:01/1:01 7 13:02/13:02 2 03:04/03:04 3
rs_1 0 1:01/11:01 5 13:02/49:01 2 03:04/15:02 3
rs_1 0 1:01/2:01 4 13:02/57:01 2 03:04/7:01 3
rs_1 1 1:01/2:05 3 13:02/8:01 4 06:02/06:02 3
rs_1 1 1:01/24:02 3 14:01/14:02 3 06:02/15:02 3
rs_1 1 1:01/24:02 3 14:01/14:02 2 06:02/15:02 3
rs_2 0 1:01/31:01 3 15:01/15:01 1 06:02/3:03 4
rs_2 0 11:01/2:01 4 15:01/18:01 1 06:02/3:04 1
使用 data.table
包可能更容易做到这一点。内联解释。
library(data.table)
#convert into a long format
longDat <- melt(dat, measure.vars=patterns("^rs"), variable.name="rs_id",
value.name="val_id")
#for each group of rs_id (rs_1, ..., rs_60) and val_id in (0,1,2),
#count the frequency of each code
longDat[,
unlist(
lapply(c("A.Ag","B.Ag","C.Ag"),
function(x) setNames(aggregate(get(x), list(get(x)), length), c("Code", x))
),
recursive=FALSE),
by=c("rs_id", "val_id")]
这是您要找的吗?这有帮助吗?
数据:
library(data.table)
dat <- fread("rs_1,rs_2,rs_3,rs_4,rs_60,A.Ag,B.Ag,C.Ag
0,0,1,2,1,02:/01,02:/07,03:07/04:01
1,2,1,2,0,02:/01,02:/07,03:07/04:01
2,1,1,2,2,02:/01,02:/07,03:07/04:01
0,0,1,0,2,02:/01,02:/07,03:07/04:01")
编辑:OP 请求检索每个 rs_id、val_id 和 *.Ag
的前 3 名
每次做一个 *.Ag 可能更具可读性,计数然后取前 3,最后合并所有结果如下:
library(data.table)
#convert into a long format
longDat <- melt(dat, measure.vars=patterns("^rs"), variable.name="rs_id",
value.name="val_id")
ids <- c("rs_id", "val_id")
Reduce(function(dt1,dt2) merge(dt1,dt2,by=ids,all=TRUE),
lapply(c("A.Ag","B.Ag","C.Ag"), function(x) {
res <- longDat[, list(.N), by=c(ids, x)][order(-N)]
setnames(res[, head(.SD ,3L), by=ids], c(x, "N"), c(paste0(x,"_Code"), x))
}))
我有一个包含 63 列和 50 行的数据框。我在下面给出了一个玩具数据集。
>df
rs_1 rs_2 rs_3 rs_4 ... rs_60 A.Ag B.Ag C.Ag
0 0 1 2 ... 1 02:/01 02:/07 03:07/04:01
1 2 1 2 ... 0 02:/01 02:/07 03:07/04:01
2 1 1 2 ... 2 02:/01 02:/07 03:07/04:01
0 0 1 0 ... 2 02:/01 02:/07 03:07/04:01
现在我需要分别为每个 rs_* =0、1 和 2 找到列(A.Ag、B.Ag 和 C.Ag)的最高频率。期望的结果是例如 rs_*=0
rs_id Code A.Ag Code B.Ag Code C.Ag
rs_1 02:/01 2 02:/07 5 03:07 5
rs_2 02:/01 3 01:/05 2 05:00 4
你能帮我解决这个问题吗?我尝试了以下功能
for (i in 1:60){
if (file[,i]==0)
{
temp1 = data.frame(sort(table(file[,61]), decreasing = TRUE)) #onlr for A.Ag coulmn
temp1$Var1 = names(file)[i]
res_types = rbind(res_types, temp1)
}
}
我得到了频率数和rs_id。但是无法获取代码。谁能帮我解决这个问题?
希望的结果是
rs_id Code Combination A.A Combination B.Ag Combination C.Ag
rs_1 0 1:01/1:01 7 13:02/13:02 2 03:04/03:04 3
rs_1 0 1:01/11:01 5 13:02/49:01 2 03:04/15:02 3
rs_1 0 1:01/2:01 4 13:02/57:01 2 03:04/7:01 3
rs_1 1 1:01/2:05 3 13:02/8:01 4 06:02/06:02 3
rs_1 1 1:01/24:02 3 14:01/14:02 3 06:02/15:02 3
rs_1 1 1:01/24:02 3 14:01/14:02 2 06:02/15:02 3
rs_2 0 1:01/31:01 3 15:01/15:01 1 06:02/3:03 4
rs_2 0 11:01/2:01 4 15:01/18:01 1 06:02/3:04 1
使用 data.table
包可能更容易做到这一点。内联解释。
library(data.table)
#convert into a long format
longDat <- melt(dat, measure.vars=patterns("^rs"), variable.name="rs_id",
value.name="val_id")
#for each group of rs_id (rs_1, ..., rs_60) and val_id in (0,1,2),
#count the frequency of each code
longDat[,
unlist(
lapply(c("A.Ag","B.Ag","C.Ag"),
function(x) setNames(aggregate(get(x), list(get(x)), length), c("Code", x))
),
recursive=FALSE),
by=c("rs_id", "val_id")]
这是您要找的吗?这有帮助吗?
数据:
library(data.table)
dat <- fread("rs_1,rs_2,rs_3,rs_4,rs_60,A.Ag,B.Ag,C.Ag
0,0,1,2,1,02:/01,02:/07,03:07/04:01
1,2,1,2,0,02:/01,02:/07,03:07/04:01
2,1,1,2,2,02:/01,02:/07,03:07/04:01
0,0,1,0,2,02:/01,02:/07,03:07/04:01")
编辑:OP 请求检索每个 rs_id、val_id 和 *.Ag
的前 3 名每次做一个 *.Ag 可能更具可读性,计数然后取前 3,最后合并所有结果如下:
library(data.table)
#convert into a long format
longDat <- melt(dat, measure.vars=patterns("^rs"), variable.name="rs_id",
value.name="val_id")
ids <- c("rs_id", "val_id")
Reduce(function(dt1,dt2) merge(dt1,dt2,by=ids,all=TRUE),
lapply(c("A.Ag","B.Ag","C.Ag"), function(x) {
res <- longDat[, list(.N), by=c(ids, x)][order(-N)]
setnames(res[, head(.SD ,3L), by=ids], c(x, "N"), c(paste0(x,"_Code"), x))
}))