我试图遍历特定的对列(它们具有相似的名称)并根据条件语句创建列。
示例数据集:
set.seed(2)
df <- data.frame (id=rep(1:5),
s1=rnorm(5, 0, 3),
s2=rnorm(5, 0, 3),
s2a=rnorm(5, 0, 3),
st1=rnorm(5, 3, 3),
st2=rnorm(5, 3, 3),
st2a=rnorm(5, 3, 3))
> df
id s1 s2 s2a st1 st2 st2a
1 1 -2.6907436 0.3972609 1.252952 -3.933207 9.2724576 -4.355119
2 2 0.5545476 2.1238642 2.945258 5.635814 -0.5997775 4.431712
3 3 4.7635360 -0.7190941 -1.178086 3.107420 7.7689146 1.210325
4 4 -3.3911270 5.9534218 -3.119007 6.038486 8.8639549 5.376610
5 5 -0.2407553 -0.4163610 5.346687 4.296795 3.0148133 3.868910
列s1与列st1等配对。如果这些列之间的相等性为-3到0,我想指示1/0。 df$ys1<-ifelse(df$s1<=-3 & df$st1>=0, 1, 0)
。最终目标是创建最终变量yes_no
(1/0)以指示列对之间的任何差异是否为1,例如df$yes_no<-ifelse(df$ys1==1 | df$ys2==1 | df$ys2a==1, 1, 0)
新数据集应如下所示:
> df
id s1 s2 s2a st1 st2 st2a ys1 ys2 ys2a yes_no
1 1 -2.6907436 0.3972609 1.252952 -3.933207 9.2724576 -4.355119 0 0 0 0
2 2 0.5545476 2.1238642 2.945258 5.635814 -0.5997775 4.431712 0 0 0 0
3 3 4.7635360 -0.7190941 -1.178086 3.107420 7.7689146 1.210325 0 0 0 0
4 4 -3.3911270 5.9534218 -3.119007 6.038486 8.8639549 5.376610 1 0 1 1
5 5 -0.2407553 -0.4163610 5.346687 4.296795 3.0148133 3.868910 0 0 0 0
我确定有一种方法可以在不实际创建所有其他列的情况下进行循环(即只创建最后一列,yes_no
)但我会对如何创建这些只是为了知道感兴趣怎么做,除了更简洁的方法。
我认为一种方法是将数据集分成两组,然后在循环中使用:
firstt<-(df[,c(2:4)])
final<-(df[,c(5:7)])
或跳过它并直接尝试循环
for(i in names(df[,c(2:4)])){
r<-(df[,c(5:7)])
df[i] <-ifelse(df$[i]<=-3 & df$[r]>=0, 1, 0)
}
显然,这不会起作用,但这就是我尝试的想法。
任何帮助,将不胜感激。
答案 0 :(得分:2)
这里是基础R的解决方案:
df$yes_no <-
rowSums(mapply(function(i,r)
ifelse(df[[r]]<=-3 & df[[i]]>=0, 1, 0)
, grep("st",names(df),value=TRUE),
gsub("t","",grep("st",names(df),value=TRUE)))) >0
1-我正在使用正则表达式来提取名称。你也可以在这里使用索引。 $ X
X = "st1" "st2" "st2a"
Y = "s1" "s2" "s2a"
2-我正在使用mapply
申请成对的elemend(X的第一个元素和Y的第一个元素等等)。
3- rowSums将3列聚合在一起,&gt; 0将其转换为逻辑向量
答案 1 :(得分:1)
以下是for循环的另一种解决方案
a <- names(df[,c(2:4)])
b <- names(df[,c(5:7)])
for(i in seq_along(a)){
df$temp<-ifelse(df[,names(df)[names(df)==a[i]]]<=-3 & df[,names(df)[names(df)==b[i]]]>=0, 1, 0)
names(df)[names(df)=="temp"] <- paste0("ys", i)
}
df$yes_no <- apply(df[grep("ys", names(df))]==1,1, function(k) ifelse(TRUE %in% k, 1, 0) )
print(df)
id s1 s2 s2a st1 st2 st2a ys1 ys2 ys3 yes_no
1 1 -2.6907436 0.3972609 1.252952 -3.933207 9.2724576 -4.355119 0 0 0 0
2 2 0.5545476 2.1238642 2.945258 5.635814 -0.5997775 4.431712 0 0 0 0
3 3 4.7635360 -0.7190941 -1.178086 3.107420 7.7689146 1.210325 0 0 0 0
4 4 -3.3911270 5.9534218 -3.119007 6.038486 8.8639549 5.376610 1 0 1 1
5 5 -0.2407553 -0.4163610 5.346687 4.296795 3.0148133 3.868910 0 0 0 0