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

Eva*_*Eva 1 r function apply lapply sapply

我知道周围有很多类似的问题,但我担心无法理解这个问题,尽管很明显它很简单!

我试图通过使用列名(而不是数字)编写一个简单的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
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变种,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
Run Code Online (Sandbox Code Playgroud)

Fra*_*ank 5

这条线来自OP

dat<-within(dat,u_all<-ifelse (u1==1 | u2==1 |u3==1,1,0))
Run Code Online (Sandbox Code Playgroud)

可以改为写成

dat$u_all <- +Reduce("|", dat[, c("u1", "u2", "u3")])
Run Code Online (Sandbox Code Playgroud)

它的工作原理,就中间对象而言:

  • 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.

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

  • 非常感谢!对不起,不清楚.我没有试图避免列名,相反,我想_use_列名但不想逐个键入,因为有很多列.所以我只是在我的脚本中将你的代码编辑为`dat $ u_all < - + Reduce("|",dat [,grepl("^ u \\ d {1,}",colnames(dat))])`.工作得很好! (2认同)