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
>