【问题标题】:R- How many times does a text value show across in a row?R- 一个文本值连续显示多少次?
【发布时间】:2025-12-14 19:55:01
【问题描述】:

我在数据框中有一个我的数据,如下所示:

someName    someID  1                  2                  3
A           1       T7(P),M6(O),S6(P)  T7(P),M6(O),S6(P)  T7(P),M6(O),S6(P),S7(P)
B           2       S4(P)              S4(P)              NA
C           3       S1(P),Q9(D)        S1(P),Q9(D)        S16(P),Q9(D)
D           4       S5(P),C7(C),S4(P)  S4(P),C7(C),S4(P)  S5(P),C7(C),S14(P)
E           5       S18(P)             S18(P)             S18(P)
F           6       S1(P)              NA                 S1(P)
L           8       Z1(P)              NA                 NA
Z           9       NA                 NA                 Q100(P)

我想阅读我的df1 中的每一行并找到拆分元素的完全匹配项并计算它们。 然后在新列中显示总数cbind 到我的df1

例如在行 someName=A 中,我想用逗号分割第 1,2,3 列中的字符串并查找在所有 3 中都找到的 T7(P),因此总和为 3。@987654327 也是@。所以对于row A,总数将是3+3=6(S7(P) 被忽略,因为在任何其他列中都找不到它)。

我想忽略没有(P) 的任何其他项目,因此忽略M6(O)

Row L 的总数为 0,因为它不与任何其他列相交。

所以我可以使用apply 函数逐行执行,然后按, 拆分列

那么我怎样才能在分割值之间进行相交或匹配呢?

我的dput(df1) 是:

structure(list(someName = structure(1:8, .Label = c("A", "B", 
"C", "D", "E", "F", "L", "Z"), class = "factor"), someID = c(1L, 
2L, 3L, 4L, 5L, 6L, 8L, 9L), `1` = c("T7(P),M6(O),S6(P)", "S4(P)", 
"S1(P),Q9(D)", "S5(P),C7(C),S4(P)", "S18(P)", "S1(P)", "Z1(P)", 
NA), `2` = c("T7(P),M6(O),S6(P)", "S4(P)", "S1(P),Q9(D)", "S4(P),C7(C),S4(P)", 
"S18(P)", NA, NA, NA), `3` = c("T7(P),M6(O),S6(P),S7(P)", NA, 
"S16(P),Q9(D)", "S5(P),C7(C),S14(P)", "S18(P)", "S1(P)", NA, 
"Q100(P)")), .Names = c("someName", "someID", "1", "2", "3"), row.names = c(NA, 
-8L), class = "data.frame")

【问题讨论】:

    标签: regex r text split add


    【解决方案1】:

    这里使用正则表达式和table 的另一种方法。这个想法是从每一行中提取具有特定模式 [A-Z][0-9]+(P) 的元素,如果它们出现不止一次,则对其进行计数。

    apply(dat,1,function(xx){
        tab <- table(unlist(regmatches(xx,gregexpr('[A-Z][0-9]+\\(P\\)',xx))))
        sum(tab[tab>1])
    })
    [ 1] 6 2 2 5 3 2 0 0
    

    【讨论】:

    • 完美!谢谢你们的代码。我使用 cbind 向我的主数据框添加一列。
    【解决方案2】:

    尝试,假设您的 data.frame 被称为 test

    # collapse and split them up
    splts <- strsplit(apply(test[3:5],1,function(x) paste(x,collapse=",")),",")
    # remove all the non (P) cases
    splts <- mapply(function(x,y) x[y], splts, lapply(splts, function(x) grep("(P)",x,fixed=TRUE)))
    # sum up those that appear more than once
    test$sumtext <- sapply(splts,function(x) sum(table(x)[table(x)>1]))
    

    结果:

    > test[,c(1,2,6)]
      someName someID sumtext
    1        A      1       6
    2        B      2       2
    3        C      3       2
    4        D      4       5
    5        E      5       3
    6        F      6       2
    7        L      8       0
    8        Z      9       0
    

    【讨论】: