如何通过列名应用 ifelse 函数?

How to apply ifelse function by column names?

我知道周围有很多类似的问题,但我恐怕无法理解这个特定的问题,尽管它显然很简单!

我正在尝试编写一个简单的 ifelse 函数,通过使用 列名称 (而不是数字)应用于数据框中的一系列列。我尝试做的是创建一个 u_all 变量,如下所示,而无需重复输入列名。

dat <- data.frame(id=c(1:20),u1 = sample(c(0:1),20,replace=T) , u2 = sample(c(0:1),20,replace=T) , u3 = sample(c(0:1),20,replace=T)) 
dat<-within(dat,u_all<-ifelse (u1==1 | u2==1 |u3==1,1,0))
dat

我尝试了 apply 的许多变体,但显然我没有走在正确的轨道上,因为这些分组函数分别在每一列上复制了 ifelse 函数。

dat2 <- data.frame(id=c(1:20),u1 = sample(c(0:1),20,replace=T) , u2 = sample(c(0:1),20,replace=T) , u3 = sample(c(0:1),20,replace=T)) 

dat2<-cbind(dat2,sapply(dat2[,grepl("^u\d{1,}",colnames(dat2))],
                               function(x){ u_all<-ifelse(x==1 & !is.na(x),1,0)}))

dat2

您几乎已经完成了,这是一个解决方案,它使用对行应用并使用 all 将测试向量转换为单个数字。

dat2$u_all <- apply(dat2[,-1], MARGIN=1, FUN=function(x){ 
  any(x==1)&all(!is.na(x))*1
}
)

OP 中的这一行

dat<-within(dat,u_all<-ifelse (u1==1 | u2==1 |u3==1,1,0))

可以写成

dat$u_all <- +Reduce("|", dat[, c("u1", "u2", "u3")])

它是如何工作的,就中间对象而言:

  • D = dat[, c("u1", "u2", "u3")] 使用列的名称对数据框进行子集化。
  • r = Reduce("|", D) 通过在每对列之间放置 | 来折叠数据。结果是一个逻辑 (TRUE/FALSE) 向量。
  • 要将 r 转换为 0/1 整数向量,您可以使用 ifelse(r,1L,0L)as.integer(r)(因为 TRUE/FALSE 默认转换为 1/0)或只是一元 +,例如 +r.

如果你想避免使用列名(post我真的不清楚),你可以构造D = dat[-1]来排除第一列。