【问题标题】:how to highlight sequential string in one column based on another column如何基于另一列突出显示一列中的顺序字符串
【发布时间】:2016-03-02 13:37:28
【问题描述】:

我的数据是

    df <- structure(list(M1 = c(4L, 11L, 11L, 11L, 11L, 11L, 11L, 16L, 
16L, 16L, 16L, 16L, 16L, 16L), M2 = structure(c(14L, 1L, 2L, 
3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L), .Label = c(" B135", 
" B168", " B172", " B299", " B300", " B301", " B335", " B336", 
" B364", " B566", " B567", " B590", " B591", "A"), class = "factor"), 
    N = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L), N2 = c(470L, 14L, 12L, 16L, 9L, 14L, 14L, 24L, 15L, 
    32L, 193L, 76L, 10L, 9L)), .Names = c("M1", "M2", "N", "N2"
), class = "data.frame", row.names = c(NA, -14L))

数据是这样的

>df
#   M1    M2 N  N2
#1   4     A 1 470
#2  11  B135 1  14
#3  11  B168 1  12
#4  11  B172 1  16
#5  11  B299 1   9
#6  11  B300 1  14
#7  11  B301 1  14
#8  16  B335 1  24
#9  16  B336 1  15
#10 16  B364 1  32
#11 16  B566 1 193
#12 16  B567 1  76
#13 16  B590 1  10
#14 16  B591 1   9

我想要做的是检查 M1 并基于 M1 突出显示 M2 我想根据 M1 的相似值评估顺序 在这个例子中

#   M1    M2  N  N2
#1   4    A   1  470

所以它只是一个,我不需要突出显示它

#2  11  B135 1  14
#3  11  B168 1  12
#4  11  B172 1  16
#5  11  B299* 1   9
#6  11  B300* 1  14
#7  11  B301* 1  14

在本节中(来自 M1 的所有数据都是 11)B299、B300 和 B301 是连续的(彼此重复)所以我想用例如星号来突出显示它

#8  16  B335* 1  24
#9  16  B336* 1  15
#10 16  B364  1  32
#11 16  B566**  1 193
#12 16  B567**  1  76
#13 16  B590***  1  10
#14 16  B591***  1   9

在本节中(M1 中的所有值都是 16)B335 和 B336 是连续的,所以我用一颗星突出显示它们,然后 B566 和 B567 也用 ** 星连续,因为它们与第一个不同,对于第三顺序组等

【问题讨论】:

  • 在最后一节中你有B335*B336*,但在你的例子中没有B336。是错字吗?
  • @PierreLafortune 谢谢这是一个错字,我更正了它

标签: r


【解决方案1】:

这是一个尝试,假设值按照您的示例进行排序:

 highlight_seq <- function(x){
        #get sequences of numbers and get rid of NAs
        num_seq <- (diff(as.numeric(gsub("\\D", "", x)))==1)*1
        num_seq[is.na(num_seq)] <- 0

        #to figure out the number of each sequence, use rle
        num_seq <- rle(num_seq)

        #replace 1s by the cumsum
        num_seq$values[which(num_seq$values!=0)]=cumsum(num_seq$values)[which(num_seq$values!=0)]
        num_seq <- inverse.rle(num_seq)

        #since diff was initially used, add the first value of each sequence
        num_seq <- c(0,num_seq)
        num_seq[which(num_seq!=0)-1] <- num_seq[which(num_seq!=0)] 

        #paste asterisks in after the sequences
        return(paste0(x,sapply(num_seq,function(p) paste(rep("*",p),collapse=""))))
}

library(dplyr)
df %>% group_by(M1) %>% mutate(M2=highlight_seq(M2))


    M1      M2 N  N2
1   4       A 1 470
2  11    B135 1  14
3  11    B168 1  12
4  11    B172 1  16
5  11   B299* 1   9
6  11   B300* 1  14
7  11   B301* 1  14
8  16    B335 1  24
9  16   B363* 1  15
10 16   B364* 1  32
11 16  B566** 1 193
12 16  B567** 1  76
13 16  B568** 1  10
14 16  B569** 1   9

【讨论】:

  • 能否得到问题中提到的相同结构输出?
  • 这绝对是非常好的,但有一个小问题。它不会刷新将星标放在每个部分上,因此它正在疯狂增长。假设在那个例子中,我们有 3 个第 4、11 和 16 节,我希望每次重新开始都不会有那么多星星,你知道我的意思吗?
  • 我明白了,我编辑了,只是把它做成了一个函数,并使用group_by(M1) 将突出显示功能应用于每个部分
  • str(summ)data.table。试试summ &lt;- as.data.frame(summ)
  • 你的方法给你带来了很大的问题。你为什么要像在这个问题中那样在数字上加星号。您不能以这种方式对它们进行任何数学或组织功能。在另一个问题中,您创建了一个无用的链接,例如 3-4?这不是程序员的心态。您正在使用 R 来创建标记和刻度,就像使用钢笔和铅笔一样。最好以一种能发挥其优势的方式使用该语言,而不是左右纠结于复杂的变通方法。
猜你喜欢
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 2016-08-13
相关资源
最近更新 更多