【问题标题】:R - How can I subset rows of a dataframe using an index of integers?R - 如何使用整数索引对数据帧的行进行子集化?
【发布时间】:2020-10-13 00:22:54
【问题描述】:

我正在尝试根据出现在一个列/变量中的某个字符串的每次出现来找到一种对数据帧进行子集化或切片的方法 - 例如我想删除两次出现的字符串之间的所有行。这个问题与this question 类似,但关键区别在于我多次出现该字符串,并希望删除每对出现之间的行。我是一个 R 傻瓜,我找不到以任何优雅的方式将解决方案应用于超过两个整数的索引的方法。

假设我有以下数据框:

a <- c("one", "here is a string", "two", "three", "four", "another string", "five", "six", "yet another string", "seven", "last string")
b <- c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k")
c <- c("type1", "type1", "type1", "type1", "type1", "type1", "type2", "type2", "type2", "type2", "type2")

df <- data.frame(a,b,c)

这给出了以下内容:

print(df)

                 a b     c
1                 one a type1
2    here is a string b type1
3                 two c type1
4               three d type1
5                four e type1
6      another string f type1
7                five g type2
8                 six h type2
9  yet another string i type2
10              seven j type2
11        last string k type2

我想对其进行子集化,以便删除其中的所有行(包括字符串“string”的任何迭代):

                    a b     c
1                 one a type1
2                five g type2
8                 six h type2

使用我链接到的问题中接受的解决方案,我可以通过创建行号索引并使用索引中的前两个位置来删除第一组行:

index = grep("string", df$a)

df[-(ind[1]:ind[2]),]

但我想做的还包括删除索引中下一对整数之间的行

df[-(ind[3]:ind[4]),]

我的实际索引有 128 个整数(64 个“对”),所以像我上面所做的那样手动提取行会让人头疼。如果我找不到一个优雅的解决方案,我目前的计划是打印索引并手动提取行(tbh,这可能比写这个问题要快,但看起来很糟糕,不会教我任何东西):

print(index)

[1]  2  6  9 11

df[-c(2:6, 9:11), ]

有没有办法循环遍历索引中每对连续的整数,或者另一种方法来做我想做的事情?我不是一个经验丰富的 R 用户,在创建这个例子之前我已经搜索了我想要做的事情(我希望遵守 reprex 标准;这是我第一次提出问题)。

我在reprex中包含了列'c',因为它反映了我的实际数据的结构(对于列'c'的每次观察变化,列'a'中出现一对'string')和I'我想知道是否有办法将 group_by() 与基本子设置表达式一起使用?但这可能是一个完全的红鲱鱼。只是包括它以防万一。

【问题讨论】:

    标签: r string subset


    【解决方案1】:

    使用Map 在连续的index 对之间创建一个序列并删除这些行。获得连续对的一种方法是使用备用逻辑值。

    df[-unlist(Map(`:`, index[c(TRUE, FALSE)], index[c(FALSE, TRUE)])),]
    
    #     a b     c
    #1  one a type1
    #7 five g type2
    #8  six h type2
    

    【讨论】:

    • 效果很好,谢谢! :) 我知道这很简单,但我的基础 R 还不够好,无法弄清楚。
    【解决方案2】:

    由于我已经在 twitter 上发布了它,这里有一个 tidyverse-y 解决方案:

    df %>% mutate(stringy = grepl("string", a),
                  seq = cumsum(stringy)) %>%
           filter(seq %% 2 == 0, !stringy)
    

    技巧基本上是一样的——我们找到哪些行有你正在寻找的字符串,然后创建一种交替它们的方法(在这种情况下,使用 cumsum 添加索引,然后使用模 2)然后过滤掉赔率加上最后出现的字符串(这将是结束索引)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 2015-06-20
      相关资源
      最近更新 更多