简体   繁体   English

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

[英]How to apply ifelse function by column names?

I know there are many similar questions around but I'm afraid couldn't get my head around this particular one, though obviously it is very simple! 我知道周围也有很多类似的问题,但是恐怕无法解决这个特定的问题,尽管显然这很简单!

I am trying to write a simple ifelse function to be applied over a series of columns in a data frame by using column names (rather than numbers). 我正在尝试编写一个简单的ifelse函数,以使用列名 (而不是数字)应用于数据框中的一系列列。 What I try to do is to create a single u_all variable as shown below without typing column names repeatedly. 我试图做的是创建一个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

I tried many variants of apply but clearly I'm not on the right track as those grouping functions replicate the ifelse function on each column separately. 我尝试了apply许多变体,但显然我ifelseifelse因为这些分组函数分别在每个列上复制了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

This line from the OP 这条线来自OP

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

can instead be written as 可以改为

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

How it works, in terms of intermediate objects: 就中间对象而言,它是如何工作的:

  • D = dat[, c("u1", "u2", "u3")] uses the names of the columns to subset the data frame. D = dat[, c("u1", "u2", "u3")]使用列的名称对数据帧进行子集化。
  • r = Reduce("|", D) collapses the data by putting | r = Reduce("|", D)通过放置|折叠数据 between each pair of columns. 在每对列之间。 The result is a logical (TRUE/FALSE) vector. 结果是逻辑(TRUE / FALSE)向量。
  • To convert r to a 0/1 integer vector, you could use ifelse(r,1L,0L) or as.integer(r) (since TRUE/FALSE converts to 1/0 by default) or just the unary + , like +r . 要将r转换为0/1整数向量,可以使用ifelse(r,1L,0L)as.integer(r) (因为TRUE / FALSE默认情况下转换为1/0)或仅一元+ ,例如+r

If you want to avoid using column names (it's really not clear to me from the post), you can construct D = dat[-1] to exclude the first column instead. 如果您想避免使用列名(从帖子中我真的不清楚),则可以构造D = dat[-1]来排除第一列。

You were almost there, here's a solution using apply over rows and using all to transform a vector of tests to a single digit. 您快要准备好了,这是一个解决方案,该方法适用于行并使用all将测试向量转换为一个数字。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM