Luigi Marongiu
2021-Aug-12 12:37 UTC
[R] How to modify rows matching patter on multiple columns of dataframe?
Helo I have a dataframe whose names are similar and I would like to change the rows containing given values simultaneously. I can select the columns using library(dplyr) but I can't modify the data: ``` library(dplyr)> df <- data.frame(var1 = c(letters[1:3], letters[1:4]),+ var2 = c(LETTERS[1:7]), + var3 = c(letters[1:3], letters[1:4]), + var4 = (1:7)^2, + var5 = c("light", "light", "heavy", "heavy", "heavy", + "light", "heavy"), + stringsAsFactors = FALSE); df var1 var2 var3 var4 var5 1 a A a 1 light 2 b B b 4 light 3 c C c 9 heavy 4 a D a 16 heavy 5 b E b 25 heavy 6 c F c 36 light 7 d G d 49 heavy> select(df, matches("var[123]"))var1 var2 var3 1 a A a 2 b B b 3 c C c 4 a D a 5 b E b 6 c F c 7 d G d> df[[select(df, matches("var[123]")) == "a"]] <- "z"Error in `[[<-`(`*tmp*`, i, value = value) : recursive indexing failed at level 2> df[[select(df, contains("var1")) == "a"]] <- "z"Error in `[[<-`(`*tmp*`, i, value = value) : recursive indexing failed at level 2 ``` If I sue which, I get a wrong substitution : ```> df[which(select(df, matches("var[123]")) == "a"), ] <- "z"; dfvar1 var2 var3 var4 var5 1 z z z z z 2 b B b 4 light 3 c C c 9 heavy 4 z z z z z 5 b E b 25 heavy 6 c F c 36 light 7 d G d 49 heavy 8 <NA> <NA> <NA> <NA> <NA> 9 <NA> <NA> <NA> <NA> <NA> 10 <NA> <NA> <NA> <NA> <NA> 11 <NA> <NA> <NA> <NA> <NA> 12 <NA> <NA> <NA> <NA> <NA> 13 <NA> <NA> <NA> <NA> <NA> 14 <NA> <NA> <NA> <NA> <NA> 15 z z z z z 16 <NA> <NA> <NA> <NA> <NA> 17 <NA> <NA> <NA> <NA> <NA> 18 z z z z z ``` what is the correct syntax? Thank you -- Best regards, Luigi
Kimmo Elo
2021-Aug-12 13:17 UTC
[R] How to modify rows matching patter on multiple columns of dataframe?
Hi, something like this (a customised version based on this: https://stackoverflow.com/questions/25768305/r-replace-multiple-values-in-multiple-columns-of-dataframes-with-na ): --- snip --- col_idx<-grep("^var[123]", names(df)) m1<-as.matrix(df[,col_idx]) m1[m1=="a"]<-"z" df[col_idx]<-m1 df --- snip --- HTH, Kimmo to, 2021-08-12 kello 14:37 +0200, Luigi Marongiu kirjoitti:> Helo > I have a dataframe whose names are similar and I would like to change > the rows containing given values simultaneously. > I can select the columns using library(dplyr) but I can't modify the > data: > ``` > library(dplyr) > > df <- data.frame(var1 = c(letters[1:3], letters[1:4]), > + var2 = c(LETTERS[1:7]), > + var3 = c(letters[1:3], letters[1:4]), > + var4 = (1:7)^2, > + var5 = c("light", "light", "heavy", "heavy", > "heavy", > + "light", "heavy"), > + stringsAsFactors = FALSE); df > var1 var2 var3 var4 var5 > 1 a A a 1 light > 2 b B b 4 light > 3 c C c 9 heavy > 4 a D a 16 heavy > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy > > select(df, matches("var[123]")) > var1 var2 var3 > 1 a A a > 2 b B b > 3 c C c > 4 a D a > 5 b E b > 6 c F c > 7 d G d > > df[[select(df, matches("var[123]")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 > > df[[select(df, contains("var1")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 > ``` > If I sue which, I get a wrong substitution : > ``` > > df[which(select(df, matches("var[123]")) == "a"), ] <- "z"; df > var1 var2 var3 var4 var5 > 1 z z z z z > 2 b B b 4 light > 3 c C c 9 heavy > 4 z z z z z > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy > 8 <NA> <NA> <NA> <NA> <NA> > 9 <NA> <NA> <NA> <NA> <NA> > 10 <NA> <NA> <NA> <NA> <NA> > 11 <NA> <NA> <NA> <NA> <NA> > 12 <NA> <NA> <NA> <NA> <NA> > 13 <NA> <NA> <NA> <NA> <NA> > 14 <NA> <NA> <NA> <NA> <NA> > 15 z z z z z > 16 <NA> <NA> <NA> <NA> <NA> > 17 <NA> <NA> <NA> <NA> <NA> > 18 z z z z z > ``` > > what is the correct syntax? > Thank you >
Eric Berger
2021-Aug-12 14:46 UTC
[R] How to modify rows matching patter on multiple columns of dataframe?
Hi Luigi, I would take a slightly different approach. Maybe this is helpful. idV <- grep("var[123]",colnames(df)) df[,idV][df[,idV]=="a"] <- "z" df var1 var2 var3 var4 var5 1 z A z 1 light 2 b B b 4 light 3 c C c 9 heavy 4 z D z 16 heavy 5 b E b 25 heavy 6 c F c 36 light 7 d G d 49 heavy HTH, Eric On Thu, Aug 12, 2021 at 3:38 PM Luigi Marongiu <marongiu.luigi at gmail.com> wrote:> Helo > I have a dataframe whose names are similar and I would like to change > the rows containing given values simultaneously. > I can select the columns using library(dplyr) but I can't modify the data: > ``` > library(dplyr) > > df <- data.frame(var1 = c(letters[1:3], letters[1:4]), > + var2 = c(LETTERS[1:7]), > + var3 = c(letters[1:3], letters[1:4]), > + var4 = (1:7)^2, > + var5 = c("light", "light", "heavy", "heavy", "heavy", > + "light", "heavy"), > + stringsAsFactors = FALSE); df > var1 var2 var3 var4 var5 > 1 a A a 1 light > 2 b B b 4 light > 3 c C c 9 heavy > 4 a D a 16 heavy > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy > > select(df, matches("var[123]")) > var1 var2 var3 > 1 a A a > 2 b B b > 3 c C c > 4 a D a > 5 b E b > 6 c F c > 7 d G d > > df[[select(df, matches("var[123]")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 > > df[[select(df, contains("var1")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 > ``` > If I sue which, I get a wrong substitution : > ``` > > df[which(select(df, matches("var[123]")) == "a"), ] <- "z"; df > var1 var2 var3 var4 var5 > 1 z z z z z > 2 b B b 4 light > 3 c C c 9 heavy > 4 z z z z z > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy > 8 <NA> <NA> <NA> <NA> <NA> > 9 <NA> <NA> <NA> <NA> <NA> > 10 <NA> <NA> <NA> <NA> <NA> > 11 <NA> <NA> <NA> <NA> <NA> > 12 <NA> <NA> <NA> <NA> <NA> > 13 <NA> <NA> <NA> <NA> <NA> > 14 <NA> <NA> <NA> <NA> <NA> > 15 z z z z z > 16 <NA> <NA> <NA> <NA> <NA> > 17 <NA> <NA> <NA> <NA> <NA> > 18 z z z z z > ``` > > what is the correct syntax? > Thank you > > -- > Best regards, > Luigi > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Rui Barradas
2021-Aug-12 16:59 UTC
[R] How to modify rows matching patter on multiple columns of dataframe?
Hello, And another way, with which(., arr.ind = TRUE). In two steps, to make it clearer. i <- which(df[grep("var[123]", names(df))] == "a", arr.ind = TRUE) df[i] <- "z" df # var1 var2 var3 var4 var5 #1 z A z 1 light #2 b B b 4 light #3 c C c 9 heavy #4 z D z 16 heavy #5 b E b 25 heavy #6 c F c 36 light #7 d G d 49 heavy Hope this helps, Rui Barradas ?s 13:37 de 12/08/21, Luigi Marongiu escreveu:> Helo > I have a dataframe whose names are similar and I would like to change > the rows containing given values simultaneously. > I can select the columns using library(dplyr) but I can't modify the data: > ``` > library(dplyr) >> df <- data.frame(var1 = c(letters[1:3], letters[1:4]), > + var2 = c(LETTERS[1:7]), > + var3 = c(letters[1:3], letters[1:4]), > + var4 = (1:7)^2, > + var5 = c("light", "light", "heavy", "heavy", "heavy", > + "light", "heavy"), > + stringsAsFactors = FALSE); df > var1 var2 var3 var4 var5 > 1 a A a 1 light > 2 b B b 4 light > 3 c C c 9 heavy > 4 a D a 16 heavy > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy >> select(df, matches("var[123]")) > var1 var2 var3 > 1 a A a > 2 b B b > 3 c C c > 4 a D a > 5 b E b > 6 c F c > 7 d G d >> df[[select(df, matches("var[123]")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 >> df[[select(df, contains("var1")) == "a"]] <- "z" > Error in `[[<-`(`*tmp*`, i, value = value) : > recursive indexing failed at level 2 > ``` > If I sue which, I get a wrong substitution : > ``` >> df[which(select(df, matches("var[123]")) == "a"), ] <- "z"; df > var1 var2 var3 var4 var5 > 1 z z z z z > 2 b B b 4 light > 3 c C c 9 heavy > 4 z z z z z > 5 b E b 25 heavy > 6 c F c 36 light > 7 d G d 49 heavy > 8 <NA> <NA> <NA> <NA> <NA> > 9 <NA> <NA> <NA> <NA> <NA> > 10 <NA> <NA> <NA> <NA> <NA> > 11 <NA> <NA> <NA> <NA> <NA> > 12 <NA> <NA> <NA> <NA> <NA> > 13 <NA> <NA> <NA> <NA> <NA> > 14 <NA> <NA> <NA> <NA> <NA> > 15 z z z z z > 16 <NA> <NA> <NA> <NA> <NA> > 17 <NA> <NA> <NA> <NA> <NA> > 18 z z z z z > ``` > > what is the correct syntax? > Thank you >