基于组的相同行的新列

时间:2019-08-27 18:11:39

标签: r dplyr

我有一些数据,如下所示:

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

3 个答案:

答案 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