我有一个数据框,我想创建一个应用在行内工作的函数的新变量。请参阅下面的示例。
library(tidyverse)
n <- 100
z0 <- data.frame(A = sample(c("y","n",NA), n, replace = T, prob = c(.4,.4,.1)),
B = sample(c("y","n",NA), n, replace = T, prob = c(.4,.4,.1)),
C = sample(c("y","n",NA), n, replace = T, prob = c(.4,.4,.1)))
z0 %>% apply(1, function(x) any("y" == x)) -> z0$new
summary(z0)
我想用mutate做这件事,但我失败了。我很感激任何建议。
答案 0 :(得分:2)
这是一个整齐的方法。让我们创建一个具有所有可能性的数据框,以确保不会遗漏任何内容。
library(tidyverse)
(z0 <- data_frame(A = c("y", "n", NA, NA, NA),
B = c("n", "n", "y", "n", NA),
C = c("n", "n", "n", "n", NA)))
#> # A tibble: 5 x 3
#> A B C
#> <chr> <chr> <chr>
#> 1 y n n
#> 2 n n n
#> 3 <NA> y n
#> 4 <NA> n n
#> 5 <NA> <NA> <NA>
这是一种使用purrr::pmap_lgl
的安全方法,要求您明确输入要包含的变量,以查看"y"
可能出现的位置:
z0 %>%
mutate(new = pmap_lgl(., ~ any("y" == c(..1, ..2, ..3))))
这是一种使用purrrlyr
(一个包含purrr
孤立函数的小包的方法),它的好处是可以使用...
来表示所有变量:
z0 %>%
purrrlyr::by_row(~ any("y" == ...), .collate = "rows", .to = "new")
两者都给出了相同的结果:
#> # tibble [5 × 4]
#> A B C new
#> <chr> <chr> <chr> <lgl>
#> 1 y n n TRUE
#> 2 n n n FALSE
#> 3 <NA> y n TRUE
#> 4 <NA> n n NA
#> 5 <NA> <NA> <NA> NA
编辑:第一个解决方案(所谓的“安全”)不适用于因子变量(可能还有其他类)as discussed here。似乎事情被强制转换为数字,这就是为什么这个(非常愚蠢的)代码给出了期望的结果:
z0 %>%
mutate(new = pmap(.,
~ any(as.numeric(factor("y", levels = c("n", "y"))) ==
c(..1, ..2, ..3))))
答案 1 :(得分:2)
这将适用于因子或字符列。
library(tidyverse)
z0 %>%
mutate(new_var = rowSums(.[c('A','B','C')] == 'y', na.rm = T) > 0)
另一种选择(我猜的更慢)是使用rowwise
z0 %>%
mutate_at(c('A', 'B', 'C'), as.character) %>%
rowwise %>%
mutate(newvar = any(c(A, B, C) == 'y', na.rm = T))