我们假设我们有一个包含3列和100行的矩阵。列名称为a_dem
,b_dem
和c_blah
。让我们想象每个单元格的值可以在0到100之间。
有没有办法使用select()
,filter()
和%>%
来仅选择以" _dem"结尾的观察结果?并且有一个大于50的值?
我会想象它会沿着这些方向发展:
dat %>%
select(ends_with("dem")) %>%
filter(>50) %>%
summary()
但显然这不起作用。
那么,有没有办法做这种选择和过滤,还是我不得不求助于更复杂的事情?
答案 0 :(得分:0)
你可以这样做:
library(dplyr)
set.seed(2)
a_dem <- runif(100,0,100)
b_dem <- runif(100,0,100)
c_blah <- runif(100,0,100)
dat <- data.frame(a_dem, b_dem, c_blah)
newdat1 <- dat %>%
select(ends_with("_dem"))
filtered <- sapply(newdat1, function(x) ifelse(x>50, x, NA))
>head(filtered)
a_dem b_dem
[1,] NA NA
[2,] 70.23740 NA
[3,] 57.33263 98.06000
[4,] NA 82.89221
[5,] 94.38393 NA
[6,] 94.34750 59.59169
然后根据您下一步要做的事情,您可以轻松排除NA
值。
更新
要在dplyr
中完全执行此操作,您可以使用@ {sgp667
newdat2 <- dat %>%
select(ends_with("_dem")) %>%
mutate_each(funs(((function(x){ifelse(x>50, x, NA)})(.))))
> head(newdat2)
a_dem b_dem
1 NA NA
2 70.23740 NA
3 57.33263 98.06000
4 NA 82.89221
5 94.38393 NA
6 94.34750 59.59169
答案 1 :(得分:0)
我想到了另一种方式:
dat %>%
mutate_each(funs(over=(function(x)x>2)(.)),ends_with("dem")) %>%
mutate(all_true=all(ends_with("over"))) %>%
filter(all_true == TRUE) %>%
select(ends_with("dem"))
这可能非常详细,但您可以过滤任意数量的列。
我找到了here如何在mutate_each
中使用自定义公式。
这种方法的工作方式是mutate_each将funs()
应用于符合ends_with("dem")
条件的所有列,此处应用的函数是(function(x)x>2)(.)
这是一个匿名函数(它听起来就像它只是一个我没有打扰命名的功能)。
匿名函数的语法是:
(function(some parameters) some instructions)(values for parameters)
在这种情况下,如果x
大于2
,则函数返回TRUE,x
传递的值为.
(.
为{{1}这可行的原因是因为管道dat
)。
因此%>%
行会生成其他列,新列的名称末尾会显示“over”。
下一行创建另一个列(名为mutate_each
),该列也具有TRUE / FALSE值,如果all_true
列为all
,则为TRUE。
end_with("over")
只会移除filter
列中包含FALSE的行。
最后,all_true
仅包含与select
匹配的列
答案 2 :(得分:0)
我虽然有另一个tidyverse
解决方案:
dat %>%
select(ends_with("_dem")) %>%
map_df(function(x) ifelse(x > 50, x, NA))