Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

r - How to loop through dataset and replace values of a different sequence of columns for each row?

Problem: I have a dataset (please see sample dataset and code below) with columns all assigned a value of 0. I would like to assign the value of 1 to a specific sequence of columns, of which the start and end column numbers I calculated and stored in the columns zFlagStart and zFlagEnd. When I try to do this via a for 1:nrow(df) loop, I get the following error: numerical expression has 2 elements: only the first used

Sample code to create dataset

#create sample dataset
r1<-c(0,0,0,0,0,1,3)
r2<-c(0,0,0,0,0,3,5)
df<-as.data.frame(rbind(r1,r2))
names(df)<-c("Flag1","Flag2","Flag3","Flag4","Flag5","zFlagStart","zFlagEnd")

Sample dataset created:

   Flag1 Flag2 Flag3 Flag4 Flag5 zFlagStart zFlagEnd
     0     0     0     0     0          1        3
     0     0     0     0     0          3        5

Sample dataset desired:

   Flag1 Flag2 Flag3 Flag4 Flag5 zFlagStart zFlagEnd
    1     1     1     0     0          1        3
    0     0     1     1     1          3        5

Failed for loop and error:

for ( i in 1:nrow(df)){
  
  df[i, c(df$zFlagStart:df$zFlagEnd)] <- 1
}

Warning messages:
1: In df$zFlagStart:df$zFlagEnd :
  numerical expression has 2 elements: only the first used



Edit: Here is the solution thanks to @ThomasIsCoding:

df2<-as.data.frame( t(apply(df, 1, function(v) replace(v, gsub("\D", "", names(v)) %in% seq(v["zFlagStart"], v["zFlagEnd"]), 1))))  


   Flag1 Flag2 Flag3 Flag4 Flag5 zFlagStart zFlagEnd
r1     1     1     1     0     0          1        3
r2     0     0     1     1     1          3        5
question from:https://stackoverflow.com/questions/65853871/how-to-loop-through-dataset-and-replace-values-of-a-different-sequence-of-column

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try apply below

df[] <- t(apply(df, 1, function(v) replace(v, gsub("\D", "", names(v)) %in% seq(v["zFlagStart"], v["zFlagEnd"]), 1)

which gives

> df
   Flag1 Flag2 Flag3 Flag4 Flag5 zFlagStart zFlagEnd
r1     1     1     1     0     0          1        3
r2     0     0     1     1     1          3        5

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...