鉴于我有一个像这样的数据框:
x <- data.frame(d1 = c(1,0,1,3,5), d2 = c(0,0,1,1,0))
# d1 d2
# 1 1 0
# 2 0 0
# 3 1 1
# 4 3 1
# 5 5 0
如果c1或c2等于1,而如果两个都不等于0,如何创建等于1的新列呢?像这样:
# d1 d2 R
# 1 1 0 1
# 2 0 0 0
# 3 1 1 1
# 4 3 1 1
# 5 5 0 0
使用dplyr,我可以通过首先使用filter_at拆分数据帧,然后将结果数据帧重新绑定在一起来实现此目的。
x1 <- x %>%
filter_at(vars(starts_with("d")), any_vars(. == 1))
x1$R <- 1
x2 <- x %>%
filter_at(vars(starts_with("d")), all_vars(. != 1))
x2$R <- 0
x <- bind_rows(x1,x2)
# d1 d2 R
# 1 1 0 1
# 2 1 1 1
# 3 3 1 1
# 4 0 0 0
# 5 5 0 0
但是,此方法不仅看起来像是完成此任务的一种回旋方式,而且数据帧的顺序也发生了变化。在我看来,这不是问题,但在其他情况下可能会令人讨厌。有人知道更好的方法吗?
答案 0 :(得分:3)
如果我正确理解了您的问题,我将使用带有ifelse语句的mutate函数。
x <- data.frame(d1 = c(1,0,1,3,5), d2 = c(0,0,1,1,0))
# the | is a logical OR operator
x %>% mutate(R = ifelse(d1 ==1 | d2== 1,1,0))
d1 d2 R
1 1 0 1
2 0 0 0
3 1 1 1
4 3 1 1
5 5 0 0
答案 1 :(得分:1)
如果不确定要包含多少个d
列,可以先调整形状。
library(dplyr)
library(tidyr)
x %>%
mutate(id = row_number()) %>%
pivot_longer(starts_with('d')) %>%
group_by(id) %>%
mutate(R = as.numeric(any(value == 1))) %>%
pivot_wider()
# A tibble: 5 x 4 # Groups: id [5] id R d1 d2 <int> <dbl> <dbl> <dbl> 1 1 1 1 0 2 2 0 0 0 3 3 1 1 1 4 4 1 3 1 5 5 0 5 0
答案 2 :(得分:1)
另一个选择可能是:
x %>%
mutate(R = +(rowSums(select(., starts_with("d")) == 1) != 0))
d1 d2 R
1 1 0 1
2 0 0 0
3 1 1 1
4 3 1 1
5 5 0 0
答案 3 :(得分:0)
在此处了解有关ifelse
的更多信息:
https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/ifelse
使用data.table
软件包尝试此操作:
library(data.table)
setDT(x)[,result:=ifelse(d1==1 | d2==1,1,0)]
基本R:
x$result <- ifelse(x$d1==1 | x$d2==1,1,0)
答案 4 :(得分:0)
如果以d
开头的列数有所不同,则可以在基数R中执行以下操作:
cbind(x, R = +Reduce("|",data.frame(x[startsWith(names(x),"d")]==1)))
d1 d2 R
1 1 0 1
2 0 0 0
3 1 1 1
4 3 1 1
5 5 0 0