我知道周围有许多类似的问题,但我担心无法理解这个问题,但很明显这很简单!
我正在尝试使用列名(而不是数字)编写一个简单的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
答案 0 :(得分:5)
来自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)或仅使用一元{ {1}},例如+
。如果你想避免使用列名(我在帖子中真的不清楚),你可以构建+r
来排除第一列。
答案 1 :(得分:3)
你几乎就在那里,这里有一个解决方案,使用apply over rows并使用all将测试向量转换为单个数字。
dat2$u_all <- apply(dat2[,-1], MARGIN=1, FUN=function(x){
any(x==1)&all(!is.na(x))*1
}
)