为什么R中的grepl每隔两行删除一次(虽然没有指定)
Why does grepl in R delete every second row (although this is not specified)
我想为 R 中的分析准备多个数据帧。
其中一些确实在第一行(类型 1)中包含变量标签(= 字符串),有些则不包含(类型 2)。请注意,我指的不是第一行的 header。
所有其他行都包含数值。
我的输入数据帧:
类型 1:
x-axis y-axis
0 200
5 299
4 314
17 117
类型 2:
0 200
5 299
4 314
17 117
最后,我想要在第一行中包含所有没有这些字符串的数据框。
两种类型的预期输出:
0 200
5 299
4 314
17 117
因为我不想手动检查哪些数据帧包含字符串,所以我想 运行 一个跨所有数据帧的代码,删除 "string row".
我注意到有些代码会从不包含该字符串的数据框中删除所有数据。
所以,我现在使用以下代码来防止这个问题:
df_new <- df[!grepl("x-axis", df) , ]
对于没有这些字符串的数据帧,这是完美的(=没有任何反应)。
但是,对于包含这些字符串的数据帧,R 不仅会删除这一行(很棒),还会每隔一行删除一次。
有人知道解决方案吗?
如果您在 data.frame 上调用 grepl
,它将 return 按列而不是单元格显示结果。
df <- data.frame('a' = c('th', 'the', 'tre', 'test'),
'b' = c('cat', 'cart', 'ca', 'fat'),
'c' = c('re', 'awe', 'io', 'ko'),
stringsAsFactors = FALSE)
grepl('cat', df)
[1] FALSE TRUE FALSE
如果您只想搜索一列,请使用@AndrewGustar 的解决方案并将该列传递给 grepl:
grepl('cat', df$b)
如果你想获取在任何地方都有值的行,按行应用 apply
:
apply(df, 1, function(x) sum(grepl('cat', x)))
或删除包含该值的行:
df[!apply(df, 1, function(x) sum(grepl('cat', x))),]
正如@AndrewGustar 所说,您应该将列传递给 grepl,而不是整个 data.frame。但多一点解释也可能对这里有所帮助。
grepl
的第二个参数通常应该是字符向量。但如果不是,则 R 将尝试使用 as.character
将其强制转换为一个。让我们做一个虚拟例子来看看它是如何工作的:
df = data.frame(V1=c('x', rep('foo',9)), V2 = 1:10, stringsAsFactors = F)
# V1 V2
# 1 x 1
# 2 foo 2
# 3 foo 3
# 4 foo 4
# 5 foo 5
# 6 foo 6
# 7 foo 7
# 8 foo 8
# 9 foo 9
# 10 foo 10
现在,如果我们as.character(df)
,我们得到
[1] "c(\"x\", \"foo\", \"foo\", \"foo\", \"foo\",
\"foo\", \"foo\", \"foo\", \"foo\", \"foo\")"
[2] "1:10"
grepl
作用于此将在这些元素的第一个中找到搜索字符串 'x',但在第二个元素中找不到:
grepl("x", df)
# [1] TRUE FALSE
这在 df[!grepl("x", df) , ]
中被回收到每两行 return
df_new
# V1 V2
#2 foo 2
#4 foo 4
#6 foo 6
#8 foo 8
#10 foo 10
所以解决方案是只搜索你想要的列:
df_new <- df[!grepl("x", df$V1) , ]
备注
side-effect as.character
return 第二列为 1:10
的一个有趣且可能不直观的 side-effect 是 grepl("1", df)
给出 [1] FALSE TRUE
(如预期)。但是,grepl("4", df)
returns [1] FALSE FALSE
即使 4 确实出现在第二列中。
我想为 R 中的分析准备多个数据帧。 其中一些确实在第一行(类型 1)中包含变量标签(= 字符串),有些则不包含(类型 2)。请注意,我指的不是第一行的 header。 所有其他行都包含数值。
我的输入数据帧: 类型 1:
x-axis y-axis
0 200
5 299
4 314
17 117
类型 2:
0 200
5 299
4 314
17 117
最后,我想要在第一行中包含所有没有这些字符串的数据框。 两种类型的预期输出:
0 200
5 299
4 314
17 117
因为我不想手动检查哪些数据帧包含字符串,所以我想 运行 一个跨所有数据帧的代码,删除 "string row".
我注意到有些代码会从不包含该字符串的数据框中删除所有数据。 所以,我现在使用以下代码来防止这个问题:
df_new <- df[!grepl("x-axis", df) , ]
对于没有这些字符串的数据帧,这是完美的(=没有任何反应)。 但是,对于包含这些字符串的数据帧,R 不仅会删除这一行(很棒),还会每隔一行删除一次。
有人知道解决方案吗?
如果您在 data.frame 上调用 grepl
,它将 return 按列而不是单元格显示结果。
df <- data.frame('a' = c('th', 'the', 'tre', 'test'),
'b' = c('cat', 'cart', 'ca', 'fat'),
'c' = c('re', 'awe', 'io', 'ko'),
stringsAsFactors = FALSE)
grepl('cat', df)
[1] FALSE TRUE FALSE
如果您只想搜索一列,请使用@AndrewGustar 的解决方案并将该列传递给 grepl:
grepl('cat', df$b)
如果你想获取在任何地方都有值的行,按行应用 apply
:
apply(df, 1, function(x) sum(grepl('cat', x)))
或删除包含该值的行:
df[!apply(df, 1, function(x) sum(grepl('cat', x))),]
正如@AndrewGustar 所说,您应该将列传递给 grepl,而不是整个 data.frame。但多一点解释也可能对这里有所帮助。
grepl
的第二个参数通常应该是字符向量。但如果不是,则 R 将尝试使用 as.character
将其强制转换为一个。让我们做一个虚拟例子来看看它是如何工作的:
df = data.frame(V1=c('x', rep('foo',9)), V2 = 1:10, stringsAsFactors = F)
# V1 V2
# 1 x 1
# 2 foo 2
# 3 foo 3
# 4 foo 4
# 5 foo 5
# 6 foo 6
# 7 foo 7
# 8 foo 8
# 9 foo 9
# 10 foo 10
现在,如果我们as.character(df)
,我们得到
[1] "c(\"x\", \"foo\", \"foo\", \"foo\", \"foo\",
\"foo\", \"foo\", \"foo\", \"foo\", \"foo\")"
[2] "1:10"
grepl
作用于此将在这些元素的第一个中找到搜索字符串 'x',但在第二个元素中找不到:
grepl("x", df)
# [1] TRUE FALSE
这在 df[!grepl("x", df) , ]
中被回收到每两行 return
df_new
# V1 V2
#2 foo 2
#4 foo 4
#6 foo 6
#8 foo 8
#10 foo 10
所以解决方案是只搜索你想要的列:
df_new <- df[!grepl("x", df$V1) , ]
备注
side-effect as.character
return 第二列为 1:10
的一个有趣且可能不直观的 side-effect 是 grepl("1", df)
给出 [1] FALSE TRUE
(如预期)。但是,grepl("4", df)
returns [1] FALSE FALSE
即使 4 确实出现在第二列中。