【问题标题】:Remove row if any column contains a specific string如果任何列包含特定字符串,则删除行
【发布时间】:2017-11-16 14:17:27
【问题描述】:

我正在尝试找出 R 中删除包含特定字符串的行的最佳方法,在我的例子中是“no_data”。

我有来自外部来源的数据,将 na 归为“no_data”

一个例子是这样的:

 time  |speed  |wheels
1:00   |30     |no_data
2:00   |no_data|18
no_data|no_data|no_data
3:00   |50     |18

我想浏览数据并删除任何列中包含此“no_data”字符串的每一行。我在弄清楚这一点时遇到了很多麻烦。我尝试了 sapply、filter、grep 和这三者的组合。我绝不是 r 专家,所以可能只是我错误地使用了这些。任何帮助将不胜感激。

【问题讨论】:

标签: r


【解决方案1】:

我们可以使用rowSums 来创建一个逻辑vector 和基于它的子集

df1[rowSums(df1 == "no_data")==0, , drop = FALSE]
#   time speed wheels
#4 3:00    50     18

数据

df1 <- structure(list(time = c("1:00", "2:00", "no_data", "3:00"), speed = c("30", 
"no_data", "no_data", "50"), wheels = c("no_data", "18", "no_data", 
"18")), .Names = c("time", "speed", "wheels"), class = "data.frame", 
row.names = c(NA, -4L))

【讨论】:

  • 当我执行df1 == 'no_data' 时,我得到了一些奇怪的结果。您是从 OP 读取数据框还是自己创建的?
  • @Sotos 更新了我使用的数据
  • 当我尝试这种方法时,我得到一个“字符串不是标准的明确格式”我认为这是因为我在真实数据集中混合了 char、int 和 num 变量。我没有在我的例子中表达这一点......
  • @lentz 你能检查一下str(yourdata) 这里我有character 类。如果是因子,则转换为character
  • 我相信问题是由于我在数据中的一些POSIXct 格式造成的。转换为character
【解决方案2】:

您可以使用na.strings = 'no_data'读取数据,将它们设置为NA,然后简单地省略NA(或取complete.cases),即(使用@akrun的数据集)

d1 <- read.table(text = 'time   speed  wheels
 1    1:00      30 no_data
            2    2:00 no_data      18
            3 no_data no_data no_data
            4    3:00      50      18', na.strings = 'no_data', h=TRUE)

d1[complete.cases(d1),]
#  time speed wheels
#4 3:00    50     18

#OR

na.omit(d1)
#  time speed wheels
#4 3:00    50     18

【讨论】:

  • 谢谢@akrun。我无法直接从 OP 数据中获取它,因为某些元素是“no_data”,其他元素是“no_data”,而其他元素仍然是个谜 :)
【解决方案3】:

两个dplyr 选项:(使用Akrun 的数据from this answer

library(dplyr)

## using the newer across()

df1 %>% filter(across(everything(), ~ !grepl("no_data", .)))
#>   time speed wheels
#> 1 3:00    50     18

## with the superseded filter_all

df1 %>% filter_all(all_vars(!grepl("no_data", .)))
#>   time speed wheels
#> 1 3:00    50     18

警告
这仅在您想删除该字符串的所有行时才有效。如果您想get 包含此字符串的所有行,all_vars(grepl('no_data',.)(没有 !)是不够的:这只会获取 all 列包含细绳。 在这种情况下,请改用filter_all(any_vars())

【讨论】:

    【解决方案4】:

    akrun 的答案是快速、正确且尽可能简单的 :) 但是,如果你想让你的生活更复杂,你也可以这样做:

    dat
         time   speed  wheels
    1    1:00      30 no_data
    2    2:00 no_data      18
    3 no_data no_data no_data
    4    3:00      50      18
    
    dat$new <- apply(dat[,1:3], 1, function(x) any(x %in% c("no_data")))
    dat <- dat[!(dat$new==TRUE),]
    dat$new <- NULL
    
    dat
      time speed wheels
    4 3:00    50     18
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 2011-02-25
      • 2021-09-17
      • 2018-07-26
      • 2021-03-17
      相关资源
      最近更新 更多