如何 select 包含某些 strings/characters 的特定列?
How to select specific columns containing certain strings/characters?
我有这个数据框:
df1 <- data.frame(a = c("correct", "wrong", "wrong", "correct"),
b = c(1, 2, 3, 4),
c = c("wrong", "wrong", "wrong", "wrong"),
d = c(2, 2, 3, 4))
a b c d
correct 1 wrong 2
wrong 2 wrong 2
wrong 3 wrong 3
correct 4 wrong 4
并且只想 select 带有字符串 'correct' 或 'wrong' 的列(即 df1 中的 b 和 d 列),这样我就得到了这个数据框:
df2 <- data.frame(a = c("correct", "wrong", "wrong", "correct"),
c = c("wrong", "wrong", "wrong", "wrong"))
a c
1 correct wrong
2 wrong wrong
3 wrong wrong
4 correct wrong
我可以使用 dplyr 来做这个吗?如果没有,我可以使用什么功能来做到这一点?我给出的示例很简单,因为我可以这样做 (dplyr):
select(df1, a, c)
但是,在我的实际数据框中,我有大约 700 variables/columns 和几百列包含字符串 'correct' 或 'wrong' 并且我不知道 variable/column 名字。
关于如何快速执行此操作的任何建议?非常感谢!
您可以使用基础 R
Filter
,它将对 df1
的每个列进行操作,并保留所有满足函数逻辑测试的列:
Filter(function(u) any(c('wrong','correct') %in% u), df1)
# a c
#1 correct wrong
#2 wrong wrong
#3 wrong wrong
#4 correct wrong
你也可以使用grepl
:
Filter(function(u) any(grepl('wrong|correct',u)), df1)
----更新-----
谢谢比维尔上校。多么优雅的解决方案。我会更多地使用 Filter
。
我也想检查速度解决方案,以防时间是一个重要因素:
locator <- apply(df1, 2, function(x) grepl("correct|wrong", x))
index <- apply(locator, 2, any)
newdf <- df1[,!index]
我将您的数据框扩展到 500,000 列:
dftest <- as.data.frame(replicate(500000, df1[,1]))
然后使用 apply
、使用 grepl 的 Filter
和使用模式 %in%:
的 Filter
测试函数的系统时间
f <- function() {
locator <- apply(dftest, 2, function(x) grepl("correct|wrong", x))
index <- apply(locator, 2, any)
newdf <- dftest[,!index]
}
f1 <- function() {newdf <- (Filter(function(x) any(c("wrong", "correct") %in% x), dftest))}
f2 <- function() {newdf <- Filter(function(u) any(grepl('wrong|correct',u)), dftest)}
system.time(f())
user system elapsed
24.32 0.00 24.35
system.time(f1())
user system elapsed
2.31 0.00 2.34
system.time(f2())
user system elapsed
8.66 0.01 8.71
上校的解决方案是迄今为止最好的解决方案。它很干净,性能最好。 --credit @akrun data.frame 建议。
我有这个数据框:
df1 <- data.frame(a = c("correct", "wrong", "wrong", "correct"),
b = c(1, 2, 3, 4),
c = c("wrong", "wrong", "wrong", "wrong"),
d = c(2, 2, 3, 4))
a b c d
correct 1 wrong 2
wrong 2 wrong 2
wrong 3 wrong 3
correct 4 wrong 4
并且只想 select 带有字符串 'correct' 或 'wrong' 的列(即 df1 中的 b 和 d 列),这样我就得到了这个数据框:
df2 <- data.frame(a = c("correct", "wrong", "wrong", "correct"),
c = c("wrong", "wrong", "wrong", "wrong"))
a c
1 correct wrong
2 wrong wrong
3 wrong wrong
4 correct wrong
我可以使用 dplyr 来做这个吗?如果没有,我可以使用什么功能来做到这一点?我给出的示例很简单,因为我可以这样做 (dplyr):
select(df1, a, c)
但是,在我的实际数据框中,我有大约 700 variables/columns 和几百列包含字符串 'correct' 或 'wrong' 并且我不知道 variable/column 名字。
关于如何快速执行此操作的任何建议?非常感谢!
您可以使用基础 R
Filter
,它将对 df1
的每个列进行操作,并保留所有满足函数逻辑测试的列:
Filter(function(u) any(c('wrong','correct') %in% u), df1)
# a c
#1 correct wrong
#2 wrong wrong
#3 wrong wrong
#4 correct wrong
你也可以使用grepl
:
Filter(function(u) any(grepl('wrong|correct',u)), df1)
----更新-----
谢谢比维尔上校。多么优雅的解决方案。我会更多地使用 Filter
。
我也想检查速度解决方案,以防时间是一个重要因素:
locator <- apply(df1, 2, function(x) grepl("correct|wrong", x))
index <- apply(locator, 2, any)
newdf <- df1[,!index]
我将您的数据框扩展到 500,000 列:
dftest <- as.data.frame(replicate(500000, df1[,1]))
然后使用 apply
、使用 grepl 的 Filter
和使用模式 %in%:
Filter
测试函数的系统时间
f <- function() {
locator <- apply(dftest, 2, function(x) grepl("correct|wrong", x))
index <- apply(locator, 2, any)
newdf <- dftest[,!index]
}
f1 <- function() {newdf <- (Filter(function(x) any(c("wrong", "correct") %in% x), dftest))}
f2 <- function() {newdf <- Filter(function(u) any(grepl('wrong|correct',u)), dftest)}
system.time(f())
user system elapsed
24.32 0.00 24.35
system.time(f1())
user system elapsed
2.31 0.00 2.34
system.time(f2())
user system elapsed
8.66 0.01 8.71
上校的解决方案是迄今为止最好的解决方案。它很干净,性能最好。 --credit @akrun data.frame 建议。