【问题标题】:R data.table: label "identity" of consecutive values based on values of other columns?R data.table:根据其他列的值标记连续值的“身份”?
【发布时间】:2017-04-25 21:52:18
【问题描述】:

我有以下data.table(它要大得多,但这显示了这种结构)

library(data.table)

dt = data.table(first_column = c("A", "B", "B", "B", "C", "A", "A", "A", "D", "B", "A", "A"), second_column =c(0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0))

> dt
    first_column second_column
 1:            A             0
 2:            B             1
 3:            B             1
 4:            B             1
 5:            C             0
 6:            A             0
 7:            A             0
 8:            A             1
 9:            D             1
10:            B             1
11:            A             1
12:            A             0
....

生成的 data.table 应该如下所示:

  first_column  second_column    identity    percent
0             A              0           0          0
1             B              1          AB        1.0
2             B              1          AB        1.0
3             B              1          AB        1.0
4             C              0           0          0
5             A              0           0          0
6             A              0           0          0
7             A              1       mixed       0.75  # 3/4, 3-AB, 4-total
8             D              1       mixed       0.75
9             B              1       mixed       0.75
10            A              1       mixed       0.75
11            A              0           0          0 
....

first_column 列具有 A、B、C 和 D 行的每一行。在第二列中,有一个表示一组值的二进制标签。所有连续的 1 分组都是唯一的“组”,例如第 1-3 行是一组,第 7-10 行是另一组。

我想通过“AB”(该组仅由 A 或 B 组成)、“CD”(该组仅由 C 或 D 组成)或“标记”这些组中的每一个混合”(如果有混合物,例如所有 B 和一个 C)。了解这些分组中的一些“如何”与百分比混合也很有用,即 AB 在总标签中的百分比。如果只有A或B,标识应该是AB。如果只有 C 或 D,标识应该是 CD。它是 A、B、C 和/或 D 的混合物,然后将其混合。百分比是(AB 行数)/(总行数)

对于identity 列,我怀疑可以使用ifelse() 语句,例如

dt$identity = ifelse( ((dt$second_column == 1) & (dt$first_column == "A") & (dt$first_column == "B") & (dt$first_column != "C") & (dt$first_column != "D")), "AB", 0)   

dt$identity = ifelse( ((dt$second_column == 1) & (dt$identity != "AB") & (dt$first_column == "C") & (dt$first_column == "D") & (dt$first_column != "A") & (dt$first_column != "B")), "CD", 0)  

但我在定义“混合大小写”时遇到了逻辑上的ifelse() 困难。我也完全不确定如何衡量 AB/所有行的百分比。

【问题讨论】:

    标签: r dataframe data.table


    【解决方案1】:

    您可以使用rleiddata.table 来获得您想要的。我使用rleid 获取分组变量,然后根据每个组的条件创建身份和百分比变量。感谢@DavidArenburg 的建议!

    dt[,c("identity", "percent") := list(if(all(first_column == "A") | all(first_column == "B")) "AB"
                                          else if (all(first_column == "C") | all(first_column == "D")) "CD"
                                          else "mixed", sum(first_column %in% c("A","B")) / .N), by =  rleid(second_column)]
    dt[second_column==0, c("identity","percent") := list("0", 0)]
    
    dt
     #       first_column second_column identity percent
     #1:            A             0        0    0.00
     #2:            B             1       AB    1.00
     #3:            B             1       AB    1.00
     #4:            B             1       AB    1.00
     #5:            C             0        0    0.00
     #6:            A             0        0    0.00
     #7:            A             0        0    0.00
     #8:            A             1    mixed    0.75
     #9:            D             1    mixed    0.75
    #10:            B             1    mixed    0.75
    #11:            A             1    mixed    0.75
    #12:            A             0        0    0.00
    

    你可以链接调用,但我没有为了可读性。

    【讨论】:

    • @Frank 这是有道理的——刚刚更新了我的答案。非常感谢这些提示 - 如果您认为应该更改其他任何内容,请告诉我
    • 感谢您的帮助!我还在学习:你能解释一下你为什么使用rleid吗?
    • 我使用rleid 来获取分组。这是将我们所有的1 运行分组在一起的非常简单的方法。如果您查看rleid(dt$second_column),您可以看到这将如何为每次运行生成一个单独的数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2022-07-08
    相关资源
    最近更新 更多