【问题标题】:New column based on identical rows of group基于相同组行的新列
【发布时间】:2019-08-27 18:11:39
【问题描述】:

我有一些数据如下图:

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)。如果一个组中只有两行并且这两行不同,则给出不同的值。如果多于两行,则为相同的行赋予相同的值,而为其他行赋予不同的值。组中所有不同的行将具有相同的值。

我从dplyr 尝试了group_by,但不知道如何从那里继续。显示所需的输出。

输出:

Sample_Name     RP   Outlier rs10033147 rs1019916 rs1040870 rs10457834 rs10796216 rs10882854   ID
31  2011          25 -5.408103         AB        AA        AA         AB         AB         AB   0
33  10145         25 -5.205900         AB        BB        BB         AB         BB         AB   1 
5   2300       10647 -5.361135         AA        AA        AA         AA         AB         AA   0
21  20110      10647 -5.043994         AA        AB        AA         BB         AB         BB   1
24  2013       10647 -5.480397         AA        AB        AA         BB         AB         BB   1
28  200        10647 -4.635197         AA        AB        AA         BB         AB         BB   1
2   20110      11458 -4.935565         BB        AA        BB         AA         AB         BB   1
9   2311       11458 -4.913464         BB        AA        BB         AA         AB         BB   1
32  200901     11458 -4.721801         BB        AA        BB         AA         AB         BB   1

【问题讨论】:

  • 我相信你可以在这里使用“排序超过分区”的逻辑。试试 plyr 中的 ddply 函数。

标签: r dplyr


【解决方案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

【讨论】:

  • 感谢您的回答,但RP = 11458 应该是 2,因为您已经分配了类似的 rows 2 值。
  • @AwaitedOne 我刚刚分配了rleid即相对id)。您可以采取额外的步骤并根据我拥有的ID 列创建所需的列。我认为你的逻辑有一些缺陷。假设您有三个唯一的行。第三个将获得ID == 2,而您说2 分配给重复的行。你可能想重温一下。
【解决方案2】:

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

【讨论】:

  • 您可以通过连接变量来解决这个问题。请参阅我提出的解决方案。
【解决方案3】:

以下代码有效。它创建两个“分区等级”并从另一个中减去一个。请注意,我相信根据您上面的逻辑,最后一个分组(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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-03
    • 2014-04-28
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多