首页 > 解决方案 > 如何限制“grepl”函数只搜索一列中的字符串?

问题描述

我正在处理一个非常大的数据集,并尝试使用该grepl函数从 47 列中的一列(变量)中提取一个小字符串。这是我使用的代码,

x<-ebd_whbnut_relJun.2020[grepl("migrat", ebd_whbnut_relJun.2020[["SPECIES.COMMENTS"]]),]

在其中,我试图仅从“SPECIES.COMMENTS”列中提取对字符串“migrat”的任何提及。“ebd_whbnut_relJun.2020”是文件名。

我运行了代码并收到了 49 个条目,但它以“47 个变量的 49 个 obs.”的形式返回。一些条目仅包含来自正确列的条目,但其他条目显然包含来自许多其他列的信息。因此,我无法将数据导出到 Excel 并给出错误消息“libxlsxwriter 中的错误:'字符串超出 Excel 的 32,767 个字符的限制。'”

这是对 grepl 函数的使用过于原始和广泛,还是像缺少逗号/括号一样简单?

标签: rstringgrepl

解决方案


我将使用diamonds来自的数据集演示一些技术ggplot2(尽管不需要该包)。

data("diamonds", package = "ggplot2")
dat <- as.data.frame(head(diamonds))
dat
#   carat       cut color clarity depth table price    x    y    z
# 1  0.23     Ideal     E     SI2  61.5    55   326 3.95 3.98 2.43
# 2  0.21   Premium     E     SI1  59.8    61   326 3.89 3.84 2.31
# 3  0.23      Good     E     VS1  56.9    65   327 4.05 4.07 2.31
# 4  0.29   Premium     I     VS2  62.4    58   334 4.20 4.23 2.63
# 5  0.31      Good     J     SI2  63.3    58   335 4.34 4.35 2.75
# 6  0.24 Very Good     J    VVS2  62.8    57   336 3.94 3.96 2.48
grep("Good", dat$cut, value = TRUE)
# [1] "Good"      "Good"      "Very Good"
dat$cut[ grepl("Good", dat$cut) ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal
dat[ grepl("Good", dat$cut), "cut" ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal

请注意,如果您使用tbl_dfor data.table,则列选择的行为会有所不同:

as_tibble(dat)[ grepl("Good", dat$cut), "cut" ]
# # A tibble: 3 x 1
#   cut      
#   <ord>    
# 1 Good     
# 2 Good     
# 3 Very Good
as.data.table(dat)[ grepl("Good", dat$cut), "cut" ]
#          cut
# 1:      Good
# 2:      Good
# 3: Very Good

事实上,你也可以在基础 R 中模仿这一点,同时也建议修复:

dat[ grepl("Good", dat$cut), "cut", drop = FALSE ]
#         cut
# 3      Good
# 5      Good
# 6 Very Good
as_tibble(dat)[ grepl("Good", dat$cut), "cut", drop = TRUE ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal

data.table有点不同,但如果你正在尝试,那么你已经知道:

as.data.table(dat)[ grepl("Good", cut), cut ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal

数据,以防您没有ggplot2

structure(list(carat = c(0.23, 0.21, 0.23, 0.29, 0.31, 0.24), 
    cut = structure(c(5L, 4L, 2L, 4L, 2L, 3L), .Label = c("Fair", 
    "Good", "Very Good", "Premium", "Ideal"), class = c("ordered", 
    "factor")), color = structure(c(2L, 2L, 2L, 6L, 7L, 7L), .Label = c("D", 
    "E", "F", "G", "H", "I", "J"), class = c("ordered", "factor"
    )), clarity = structure(c(2L, 3L, 5L, 4L, 2L, 6L), .Label = c("I1", 
    "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"), class = c("ordered", 
    "factor")), depth = c(61.5, 59.8, 56.9, 62.4, 63.3, 62.8), 
    table = c(55, 61, 65, 58, 58, 57), price = c(326L, 326L, 
    327L, 334L, 335L, 336L), x = c(3.95, 3.89, 4.05, 4.2, 4.34, 
    3.94), y = c(3.98, 3.84, 4.07, 4.23, 4.35, 3.96), z = c(2.43, 
    2.31, 2.31, 2.63, 2.75, 2.48)), row.names = c(NA, -6L), class = "data.frame")

推荐阅读