我有一些数据,如下所示:
Sample_Name RP Outlier rs10033147 rs1019916 rs1040870 rs10457834 rs10796216 rs10882854
31 2011 25 -5.408103 AB AA AA AB AB AB
33 10145 25 -5.205900 AB BB BB AB BB AB
5 2300 10647 -5.361135 AA AA AA AA AB AA
21 20110 10647 -5.043994 AA AB AA BB AB BB
24 2013 10647 -5.480397 AA AB AA BB AB BB
28 200 10647 -4.635197 AA AB AA BB AB BB
2 20110 11458 -4.935565 BB AA BB AA AB BB
9 2311 11458 -4.913464 BB AA BB AA AB BB
32 200901 11458 -4.721801 BB AA BB AA AB BB
我想使用RP
列对它们进行分组,并检查从第4列开始的行是否相同。我想为不同的行提供不同的值(0/1)。如果组中只有两行并且这两行不同,请提供不同的值。如果多于两行,则为相同的行赋予相同的值,而为其他行赋予不同的值。组中所有不同的行将具有相同的值。
我尝试过group_by
的{{1}},但不确定如何从那里继续。显示所需的输出。
输出:
dplyr
答案 0 :(得分:1)
library(data.table)
setDT(df1)[, temp := Reduce(function(...) paste(..., sep = "-"),
.SD[, mget(names(df1)[startsWith(names(df1), "rs")])])][,
ID := sprintf('%01d', rleid(temp)), by = RP][, temp := NULL][]
#Sample RP Outlier rs10033147 rs1019916 rs1040870 rs10457834 rs10796216 rs10882854 ID
# 2011 25 -5.408103 AB AA AA AB AB AB 1
# 10145 25 -5.205900 AB BB BB AB BB AB 2
# 2300 10647 -5.361135 AA AA AA AA AB AA 1
# 20110 10647 -5.043994 AA AB AA BB AB BB 2
# 2013 10647 -5.480397 AA AB AA BB AB BB 2
# 200 10647 -4.635197 AA AB AA BB AB BB 2
# 20110 11458 -4.935565 BB AA BB AA AB BB 1
# 2311 11458 -4.913464 BB AA BB AA AB BB 1
#200901 11458 -4.721801 BB AA BB AA AB BB 1
答案 1 :(得分:0)
使用dplyr
的解决方案(仅当每个组的唯一行不超过两个时才有效):
library(tidyverse)
df %>% group_by(RP, rs10033147, rs1019916, rs1040870, rs10457834, rs10796216, rs10882854) %>% mutate(ID = ifelse(n() > 1, 1, 0)) %>% ungroup %>% group_by(RP) %>% mutate(ID = ifelse(n() == 2 & row_number() == 2, 1, ID)) %>% ungroup()
#Sample RP Outlier rs10033147 rs1019916 rs1040870 rs10457834 rs10796216 rs10882854 ID
# 2011 25 -5.408103 AB AA AA AB AB AB 0
# 10145 25 -5.205900 AB BB BB AB BB AB 1
# 2300 10647 -5.361135 AA AA AA AA AB AA 0
# 20110 10647 -5.043994 AA AB AA BB AB BB 1
# 2013 10647 -5.480397 AA AB AA BB AB BB 1
# 200 10647 -4.635197 AA AB AA BB AB BB 1
# 20110 11458 -4.935565 BB AA BB AA AB BB 1
# 2311 11458 -4.913464 BB AA BB AA AB BB 1
#200901 11458 -4.721801 BB AA BB AA AB BB 1
答案 2 :(得分:0)
下面的代码有效。它创建两个“高于分区的等级”,并从另一个中减去一个。请注意,根据您的上述逻辑,最后一个分组(11458)应该全部为零而不是一个,因为您从零开始了新的ID组。下面的代码使用了更新的逻辑。
# Create dataframe
df = read.table(text = '
Sample_Name RP Outlier rs10033147 rs1019916 rs1040870 rs10457834 rs10796216 rs10882854
31 2011 25 -5.408103 AB AA AA AB AB AB
33 10145 25 -5.205900 AB BB BB AB BB AB
5 2300 10647 -5.361135 AA AA AA AA AB AA
21 20110 10647 -5.043994 AA AB AA BB AB BB
24 2013 10647 -5.480397 AA AB AA BB AB BB
28 200 10647 -4.635197 AA AB AA BB AB BB
2 20110 11458 -4.935565 BB AA BB AA AB BB
9 2311 11458 -4.913464 BB AA BB AA AB BB
32 200901 11458 -4.721801 BB AA BB AA AB BB
', header = T)
# Create rank by RP partition
df <- ddply(df, .(RP), transform, RP_rank= rank(RP, ties.method = "first"))
# Create rank by RP & rs partition
df$rskey <- paste0(df$rs10033147,df$rs1019916,df$rs1040870,df$rs10457834,df$rs10796216,df$rs10882854)
df <- ddply(df, .(RP, rskey), transform, RPrs_rank = rank(RP, rskey, ties.method = "first"))
# This is the key step. Subtract one partition rank from the other.
df$ID <- df$RP_rank - df$RPrs_rank
# Remove unneeded columns
df$RP_rank <- NULL; df$rskey <- NULL; df$RPrs_rank <- NULL