我有大量以" country"开头的数据框列。并以数字方式加1(例如country1
,country2
,country3
)。我想将dplyr
filter
我的数据框df
用于 ONE OR MORE 变量包含某些国家/地区名称作为值的行(即{{1} }}"),以及许多其他条件。
我已经尝试使用country1 OR country2 OR country3 %in% "Brazil
来执行此操作,但我遇到的问题是该函数与grep
函数的其余部分同时进行评估,因此我得到了一个错误信息。以下是我尝试过的内容:
filter
当然,R只是将df1 <- filter(df,
a %in% value1
& b %in% value2
& grep("^country.*", colnames(df), value = TRUE) %in% c("Brazil")
函数评估为...
grep
并返回一个逻辑向量,其中显然没有值==&#34;巴西&#34;:
& c("country1", "country2", "country3", ... ) %in% c("Brazil")
有没有办法在不费力地输入所有变量的情况下做到这一点?例如......
[1] FALSE FALSE FALSE ...
...
谢谢!
答案 0 :(得分:5)
更紧凑的版本:
df %>% filter(str_detect(country1:country3, "Brazil"))
# country1 country2 country3
# 1 A B Brazil
(需要stringr
以及dplyr
)
根据@ beginneR的评论,这也可能有用:
df %>% filter(str_detect(starts_with("country"), "Brazil"))
答案 1 :(得分:4)
这是使用碱基R
的载体化溶液dat[rowSums(dat[grepl("^country\\d+$", names(dat))] == "Brazil") > 0, ]
## Random1 Random2 country1 country2 country3
## 1 C D A B Brazil
或data.table
二进制搜索(对于大数据集来说将是某个赢家)
library(data.table)
setDT(dat)[, indx := rowSums(.SD[, grepl("^country\\d+$", names(dat)), with = F] == "Brazil") > 0]
setkey(dat, indx)[J(TRUE)]
## Random1 Random2 country1 country2 country3 indx
## 1: C D A B Brazil TRUE
数据集
dat <- data.frame(Random1 = c("C", "Brazil"), Random2 = "D",
country1 = "A", country2 = "B", country3 = c("Brazil", "C"))
# Random1 Random2 country1 country2 country3
# 1 C D A B Brazil
# 2 Brazil D A B C
答案 2 :(得分:3)
您也可以尝试这样的事情。我首先创建一个行的索引,其中“Brazil”出现在任何“country”列中,然后使用索引来对数据进行子集化/过滤:
indx <- df %>% select(starts_with("country")) %>%
mutate_each(funs(grepl("Brazil", .))) %>%
rowSums > 0
indx
#[1] TRUE FALSE
df %>% filter(indx)
# country1 country2 country3
#1 A B Brazil
df <- data.frame(country1 = "A", country2 = "B", country3 = c("Brazil", "C"))
df
# country1 country2 country3
#1 A B Brazil
#2 A B C
如果您想查找多个国家/地区名称,只需稍加修改即可将感兴趣的国家/地区名称粘贴在一起,例如:像这样:
首先,我会略微修改示例数据,以包含第三行“Argentina”。
df <- data.frame(country1 = "A", country2 = "B", country3 = c("Brazil", "C", "Argentina"))
df
# country1 country2 country3
#1 A B Brazil
#2 A B C
#3 A B Argentina
然后,您可以在向量中存储要查找的国家/地区名称:
x <- c("Brazil", "Argentina", "USA")
现在,再次构建indx,但将“x”的国家/地区名称粘贴在一起,以便grepl
查找其中任何一个(技巧是以“|”折叠 - 逻辑OR):
indx <- df %>% select(starts_with("country")) %>%
mutate_each(funs(grepl(paste(x, collapse = "|"), .))) %>%
rowSums > 0
现在,您可以采用标准方式对数据进行子集化,例如使用dplyr:
df[indx,]
# country1 country2 country3
#1 A B Brazil
#3 A B Argentina
df %>% filter(indx)
# country1 country2 country3
#1 A B Brazil
#2 A B Argentina
答案 3 :(得分:1)
您可以使用逻辑矩阵作为帮助程序并获取唯一行
dat[sort(unique(row(dat)[dat == "Brazil"])),]
# country1 country2 country3 country4 country5
# 3 Brazil Brazil Argentina Brazil Brazil
# 4 Mexico Chile Brazil Chile Argentina
# 5 Brazil Chile Argentina Brazil Argentina
# 6 Mexico Chile Argentina Brazil Brazil
另外,您可以使用which
w <- which(dat == "Brazil", arr.ind=TRUE)[,"row"]
dat[sort(unique(w)),]
dat
数据的位置为:
set.seed(25)
country <- c("Brazil", "Chile", "Argentina", "Mexico")
dat <- as.data.frame(matrix(sample(country, 30, TRUE), 6))
dat <- setNames(dat, paste0("country", 1:ncol(dat)))
答案 4 :(得分:0)
您可以将列粘贴在一起以获得超级列,然后将其grep用于巴西吗?
示例:
set.seed(1)
dat <- data.frame(matrix(sample(c(rep('Canada',10), 'Brazil'), 20, replace=T),
ncol=5),
stringsAsFactors=F)
> dat
X1 X2 X3 X4 X5
1 Canada Canada Canada Canada Canada
2 Canada Canada Canada Canada Brazil
3 Canada Brazil Canada Canada Canada
4 Canada Canada Canada Canada Canada
然后:
dat$X6 <- apply(dat, 1, paste, collapse="")
grepl('Brazil', dat$X6)
> grepl('Brazil', dat$X6)
[1] FALSE TRUE TRUE FALSE
正如预期的那样,仅对其中包含巴西的行(即2和3)返回TRUE