删除具有相同子字符串的后续元素

Remove subsequent elements with the same substring

提问人:Hack-R 提问时间:6/23/2015 最后编辑:zx8754Hack-R 更新时间:6/23/2015 访问量:52

问:

我有一个 n x 2 对象,第一列包含变量名称,第二列包含数值(分数):

 data      <- data.frame(matrix(nrow = 20, ncol = 2))
 data[, 2] <- 1:20
 data[, 1] <- c("example_a_1", "example_a_2", "example_a_3",
                "example_b_1", "example_c_1", "example_d_1",
                "example_d_2", "example_d_3", "example_f_1",
                "example_g_1", "example_g_2", "example_h_1",
                "example_i_1", "example_l_1", "example_o_1",
                "example_j_1", "example_m_1", "example_p_1",
                "example_k_1", "example_n_1")
data
            X1 X2
1  example_a_1  1
2  example_a_2  2
3  example_a_3  3
4  example_b_1  4
5  example_c_1  5
6  example_d_1  6
7  example_d_2  7
8  example_d_3  8
9  example_f_1  9
10 example_g_1 10
11 example_g_2 11
12 example_h_1 12
13 example_i_1 13
14 example_l_1 14
15 example_o_1 15
16 example_j_1 16
17 example_m_1 17
18 example_p_1 18
19 example_k_1 19
20 example_n_1 20

我不希望这个对象包含类似的变量——如果一个变量名称的前 9 个字符(在本例中)与另一个变量名称相同,那么它是重复的。在这些情况下,我只想保留第一个名称相似的变量。

我可以得到一个列表,列出哪些变量名称是重复的,如下所示:

 rep <- as.data.frame(table(substr(data[,1], 1, 9)))
 rep <- rep[rep[, 2] > 1, ]
 rep
       Var1 Freq
1 example_a    3
4 example_d    3
6 example_g    2

从而在循环或其他条件中识别它们:for

for(i in 1:nrow(data)){
  if(substr(data[i, 1], 1, 9) %in% rep[,1])){
    # What goes here?
    #   or what's another approach?
  }
}

但是,我不确定我可以使用什么逻辑来删除具有重复名称的行?

最终对象应如下所示:

data
           X1 X2
1 example_a_1  1
2 example_b_1  4
3 example_c_1  5
4 example_d_1  6
5 example_f_1  9
6 example_g_1 10
7 example_h_1 12
8 example_i_1 13
9 example_l_1 14
10 example_o_1 15
11 example_j_1 16
12 example_m_1 17
13 example_p_1 18
14 example_k_1 19
15 example_n_1 20
r

评论

0赞 talat 6/23/2015
data[!duplicated(substr(data$X1, 1, 9)), ]?
0赞 zx8754 6/23/2015
我更喜欢@RobertH使用重复的解决方案,请随时更改您接受的答案。

答:

2赞 zx8754 6/23/2015 #1

使用 dplyr:

library(dplyr)
data  <- data %>% 
            group_by(my9=substr(X1,1,9)) %>% 
            filter(row_number(my9)==1) %>% 
            select(-my9)
2赞 Michal 6/23/2015 #2

我将创建一个具有缩短名称的列,并在该列上聚合:

data$short <- substr(data[,1], 1, 9)
agg <- aggregate(data$X2~data$short, FUN=min)

我使用min是因为你似乎对每个重复名称的最小分数感兴趣

评论

0赞 Hack-R 6/23/2015
这也是一个好方法。+1 虽然在这个例子中分数是完全任意的,但在我的实际用例中,我可以这样做并用 .minmax
5赞 Robert Hijmans 6/23/2015 #3

你可以使用duplicated

short <- substr(data[,1], 1, 9)
i <- duplicated(short)
data <- data[!i , ]