Solution to replace mutate() with other solution

#There are solution to replace mutate () ?code below:
df <- data.frame(A = c(12,71,53,34,21),
                 B = c(23, 41, 32, 58, 26),
                 C=c(12,1,3,5,6),
                 D=c(12,4,7,8,11),
                 E=c(11,33,45,67,89)
                       
                       )
df
library(dplyr)
df_new<-mutate(df,Y=A-B,Z=A-C,U=A-D,W=A-E)
df_new

It depends on how esoteric you want to be but there is an interesting solution in {data.table}. You will probably have to install the {data.table} package.

 install.packages("data.table") 

Note that I am reading in the data as a data.table rather than as a data.frame.


library(data.table)
DT <- data.table(A = c(12,71,53,34,21),
                 B = c(23, 41, 32, 58, 26),
                 C=c(12,1,3,5,6),
                 D=c(12,4,7,8,11),
                 E=c(11,33,45,67,89))

NewDT <- DT

NewDT[, c("Y", "Z", "U", "W") := .(A - B, A - C, A - D, A - E )]
NewDT

# Or if you only want to keep the new variables

DX <- DT[, .(Y = A - B, Z = A - C, U = A - D, W = A - E)]
DX
1 Like

#>Can we use; for loop,,,?

It probably could be done but compared to the {dplyr} "mutate()" or the {data.table} approach I think it would be much clumsier.

The general advice in R is to only use a "for loop" if there is nothing else.

Also, Danut, what you can do depends on the version of dplyr you have access to — does your version contain the across() function?

Yes  contain across()function

The across() function is a poweful loop substitute in this context. I'm not sure if there's a difference between what my and your versions can do, but here is what can be done with mine:

df <- 
  data.frame(
    A = c(12,71,53,34,21),
    B = c(23, 41, 32, 58, 26),
    C = c(12,1,3,5,6),
    D = c(12,4,7,8,11),
    E = c(11,33,45,67,89)
  )

df
#>    A  B  C  D  E
#> 1 12 23 12 12 11
#> 2 71 41  1  4 33
#> 3 53 32  3  7 45
#> 4 34 58  5  8 67
#> 5 21 26  6 11 89
library(tidyverse)

# applying to each column, without changing column names
df |> 
  # using anonymous function of the form \(input) {...; ...; output}
  mutate(
    across(
      B:E, 
      \(column) A - column
    )
  )
#>    A   B  C  D   E
#> 1 12 -11  0  0   1
#> 2 71  30 70 67  38
#> 3 53  21 50 46   8
#> 4 34 -24 29 26 -33
#> 5 21  -5 15 10 -68
# applying to each column, but changing column names
df |> 
  mutate(
    across(
      B:E, 
      \(column) A - column,
      # construct name using internal .col variable
      .names = 'A - {.col}')
  )
#>    A  B  C  D  E A - B A - C A - D A - E
#> 1 12 23 12 12 11   -11     0     0     1
#> 2 71 41  1  4 33    30    70    67    38
#> 3 53 32  3  7 45    21    50    46     8
#> 4 34 58  5  8 67   -24    29    26   -33
#> 5 21 26  6 11 89    -5    15    10   -68
# alternative to using anonynmous function
df |> 
  mutate(
    across(
      B:E, 
      # using named function
      list(A = \(column) A - column),
      # construct name using internal .fn and .col variables
      .names = '{.fn} - {.col}')
  ) |> as_tibble()
#> # A tibble: 5 × 9
#>       A     B     C     D     E `A - B` `A - C` `A - D` `A - E`
#>   <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
#> 1    12    23    12    12    11     -11       0       0       1
#> 2    71    41     1     4    33      30      70      67      38
#> 3    53    32     3     7    45      21      50      46       8
#> 4    34    58     5     8    67     -24      29      26     -33
#> 5    21    26     6    11    89      -5      15      10     -68
# applying multiple functions to each column
df |> 
  mutate(
    across(
      B:E, 
      # using named functions, but with backticks since names are nonsyntactic
      list(
        `A - ` = \(column) A - column,
        `A + ` = \(column) A + column
      ),
      .names = '{.fn}{.col}')
  ) 
#>    A  B  C  D  E A - B A + B A - C A + C A - D A + D A - E A + E
#> 1 12 23 12 12 11   -11    35     0    24     0    24     1    23
#> 2 71 41  1  4 33    30   112    70    72    67    75    38   104
#> 3 53 32  3  7 45    21    85    50    56    46    60     8    98
#> 4 34 58  5  8 67   -24    92    29    39    26    42   -33   101
#> 5 21 26  6 11 89    -5    47    15    27    10    32   -68   110

Created on 2024-04-03 with reprex v2.0.2

full reprex (click to open)
df <- 
  data.frame(
    A = c(12,71,53,34,21),
    B = c(23, 41, 32, 58, 26),
    C = c(12,1,3,5,6),
    D = c(12,4,7,8,11),
    E = c(11,33,45,67,89)
  )

df
#>    A  B  C  D  E
#> 1 12 23 12 12 11
#> 2 71 41  1  4 33
#> 3 53 32  3  7 45
#> 4 34 58  5  8 67
#> 5 21 26  6 11 89

library(tidyverse)

# applying to each column, without changing column names
df |> 
  # using anonymous function of the form \(input) {...; ...; output}
  mutate(
    across(
      B:E, 
      \(column) A - column
    )
  )
#>    A   B  C  D   E
#> 1 12 -11  0  0   1
#> 2 71  30 70 67  38
#> 3 53  21 50 46   8
#> 4 34 -24 29 26 -33
#> 5 21  -5 15 10 -68

# applying to each column, but changing column names
df |> 
  mutate(
    across(
      B:E, 
      \(column) A - column,
      # construct name using internal .col variable
      .names = 'A - {.col}')
  )
#>    A  B  C  D  E A - B A - C A - D A - E
#> 1 12 23 12 12 11   -11     0     0     1
#> 2 71 41  1  4 33    30    70    67    38
#> 3 53 32  3  7 45    21    50    46     8
#> 4 34 58  5  8 67   -24    29    26   -33
#> 5 21 26  6 11 89    -5    15    10   -68

# alternative to using anonynmous function
df |> 
  mutate(
    across(
      B:E, 
      # using name function
      list(A = \(column) A - column),
      # construct name using internal .fn and .col variables
      .names = '{.fn} - {.col}')
  ) |> as_tibble()
#> # A tibble: 5 × 9
#>       A     B     C     D     E `A - B` `A - C` `A - D` `A - E`
#>   <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
#> 1    12    23    12    12    11     -11       0       0       1
#> 2    71    41     1     4    33      30      70      67      38
#> 3    53    32     3     7    45      21      50      46       8
#> 4    34    58     5     8    67     -24      29      26     -33
#> 5    21    26     6    11    89      -5      15      10     -68

# applying multiple functions to each column
df |> 
  mutate(
    across(
      B:E, 
      # using named functions, but with backticks since names are nonsyntactic
      list(
        `A - ` = \(column) A - column,
        `A + ` = \(column) A + column
      ),
      .names = '{.fn}{.col}')
  ) 
#>    A  B  C  D  E A - B A + B A - C A + C A - D A + D A - E A + E
#> 1 12 23 12 12 11   -11    35     0    24     0    24     1    23
#> 2 71 41  1  4 33    30   112    70    72    67    75    38   104
#> 3 53 32  3  7 45    21    85    50    56    46    60     8    98
#> 4 34 58  5  8 67   -24    92    29    39    26    42   -33   101
#> 5 21 26  6 11 89    -5    47    15    27    10    32   -68   110

Created on 2024-04-03 with reprex v2.0.2

library(tidyverse)

# applying to each column, without changing column names
df %>%
  # using anonymous function of the form \(input) {...; ...; output}
  mutate(
    across(
      B:E,
      \(column)A-column
      )
    )
reprex()
Error in parse(text = x, keep.source = TRUE) : 
  <text>:5:7: unexpected 'in'
4: 
5: Error in
         ^

Could you post a complete reprex that shows the error generated? It's very difficult to sort out what's going on without one. You can follow the instructions I posted here.

No user-supplied code found … so we’ve made some up. You’re welcome!

sprintf("Happy %s!", weekdays(Sys.Date()))
#> [1] "Happy Friday!"

Created on 2024-04-05 with reprex v2.1.0

Happy Friday to you too.

1 Like

Looks like you didn't select the code as shown, when you ran the reprex add-in.

Error in parse(text = x, keep.source = TRUE) : 
  <text>:7:4: unexpected symbol
6: 
7: No user
      ^

As I said, it's hard to know how to help without a reprex to show what's going on. If you follow the instruction in the post I linked carefully, you'll be able to post one.

you should only attempt to reprex code; if you reprex things that are not code; like a conversation; or a mix of R code and error message text ; , you can expect reprex to fail.

``` r
#Loop over columns and rows in a data frame
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(formattable)
library(reshape2)
library(data.table)
#> 
#> Attaching package: 'data.table'
#> The following objects are masked from 'package:reshape2':
#> 
#>     dcast, melt
#> The following objects are masked from 'package:dplyr':
#> 
#>     between, first, last

mac <- read.csv("D:/TEMP/sto1.csv", dec=",")
mac1<- mac %>% mutate(Lung=sample(x = c(216,213,184),
                                  size = 129, replace = TRUE))
head(mac1)
#>   Buc      MT   Kg Lung
#> 1 302 1884.48 2619  184
#> 2 296  1847.4 2568  216
#> 3 304 1869.96 2599  216
#> 4 240  1497.6 2082  184
#> 5 385  2194.5 3050  216
#> 6 302  1887.5 2624  184
mac1 <- mac1 %>% 
  mutate(Buc = as.numeric(Buc),MT=as.numeric(MT))
mac1<-mac1%>%mutate(medie=round(MT/Buc,2))
mac1<-mac1%>%mutate(Pcs=floor((medie*1000-200)/Lung))
#str(mac)
mac1<-mac1%>%mutate(CTT=MT/(Buc*Lung*Pcs/1000))

mac1<-mac1%>%mutate(util=(Buc*Lung*Pcs/1000))

head(mac1)
#>   Buc      MT   Kg Lung medie Pcs      CTT     util
#> 1 302 1884.48 2619  184  6.24  32 1.059783 1778.176
#> 2 296 1847.40 2568  216  6.24  27 1.070167 1726.272
#> 3 304 1869.96 2599  216  6.15  27 1.054730 1772.928
#> 4 240 1497.60 2082  184  6.24  32 1.059783 1413.120
#> 5 385 2194.50 3050  216  5.70  25 1.055556 2079.000
#> 6 302 1887.50 2624  184  6.25  32 1.061481 1778.176
#################


#########################
y=rep(sample(c(216,213,184),
             size = 129,
             replace=TRUE))
y
#>   [1] 184 213 213 184 184 184 213 213 213 216 213 213 213 184 184 213 216 213
#>  [19] 213 184 184 184 184 184 213 213 213 213 216 184 184 216 216 216 184 213
#>  [37] 216 216 213 216 213 184 213 184 216 216 216 216 184 216 184 213 184 184
#>  [55] 184 184 213 213 213 216 184 216 213 216 184 184 213 216 213 216 216 184
#>  [73] 184 184 213 213 216 213 216 216 213 213 213 213 216 184 213 216 216 213
#>  [91] 213 216 184 213 213 213 213 216 184 216 216 213 213 184 216 216 184 216
#> [109] 216 216 213 213 213 184 213 216 216 184 216 184 216 213 184 213 216 216
#> [127] 213 184 216

z= matrix(ncol = 10,nrow = 129)
for(year in 1:10) {
  # for each year sample the return 10000 times
  for(i in 1:129){
    z[i,year] = sample(y,1)
  }
}
colnames(z) <- paste0("V", 1:ncol(z))
head(z)
#>       V1  V2  V3  V4  V5  V6  V7  V8  V9 V10
#> [1,] 216 213 216 213 216 216 184 184 184 216
#> [2,] 216 184 213 184 184 184 216 213 216 213
#> [3,] 216 184 213 184 216 184 213 213 184 184
#> [4,] 216 213 184 216 216 184 216 216 213 216
#> [5,] 213 213 216 216 213 216 213 216 216 216
#> [6,] 213 213 213 184 213 216 213 213 184 213
data_new2 <- cbind(mac1, z)
head(data_new2)
#>   Buc      MT   Kg Lung medie Pcs      CTT     util  V1  V2  V3  V4  V5  V6  V7
#> 1 302 1884.48 2619  184  6.24  32 1.059783 1778.176 216 213 216 213 216 216 184
#> 2 296 1847.40 2568  216  6.24  27 1.070167 1726.272 216 184 213 184 184 184 216
#> 3 304 1869.96 2599  216  6.15  27 1.054730 1772.928 216 184 213 184 216 184 213
#> 4 240 1497.60 2082  184  6.24  32 1.059783 1413.120 216 213 184 216 216 184 216
#> 5 385 2194.50 3050  216  5.70  25 1.055556 2079.000 213 213 216 216 213 216 213
#> 6 302 1887.50 2624  184  6.25  32 1.061481 1778.176 213 213 213 184 213 216 213
#>    V8  V9 V10
#> 1 184 184 216
#> 2 213 216 213
#> 3 213 184 184
#> 4 216 213 216
#> 5 216 216 216
#> 6 213 184 213
#ADAUGAT
head(data_new2)
#>   Buc      MT   Kg Lung medie Pcs      CTT     util  V1  V2  V3  V4  V5  V6  V7
#> 1 302 1884.48 2619  184  6.24  32 1.059783 1778.176 216 213 216 213 216 216 184
#> 2 296 1847.40 2568  216  6.24  27 1.070167 1726.272 216 184 213 184 184 184 216
#> 3 304 1869.96 2599  216  6.15  27 1.054730 1772.928 216 184 213 184 216 184 213
#> 4 240 1497.60 2082  184  6.24  32 1.059783 1413.120 216 213 184 216 216 184 216
#> 5 385 2194.50 3050  216  5.70  25 1.055556 2079.000 213 213 216 216 213 216 213
#> 6 302 1887.50 2624  184  6.25  32 1.061481 1778.176 213 213 213 184 213 216 213
#>    V8  V9 V10
#> 1 184 184 216
#> 2 213 216 213
#> 3 213 184 184
#> 4 216 213 216
#> 5 216 216 216
#> 6 213 184 213
library(tidyverse)
#> Warning: package 'readr' was built under R version 4.3.2
library(conflicted)
library(dplyr)
(colnames <- colnames(data_new2))
#>  [1] "Buc"   "MT"    "Kg"    "Lung"  "medie" "Pcs"   "CTT"   "util"  "V1"   
#> [10] "V2"    "V3"    "V4"    "V5"    "V6"    "V7"    "V8"    "V9"    "V10"
(cols_to_process <- colnames[startsWith(colnames, "V")])
#>  [1] "V1"  "V2"  "V3"  "V4"  "V5"  "V6"  "V7"  "V8"  "V9"  "V10"
(new_names <- sub("^V", "W", cols_to_process))
#>  [1] "W1"  "W2"  "W3"  "W4"  "W5"  "W6"  "W7"  "W8"  "W9"  "W10"
for(i in seq_along(cols_to_process)){
  medie_i <- data_new2$medie[[i]]
  MT_i <- data_new2$MT[[i]]
  Buc_i<-data_new2$Buc[[i]]
  data_new2[[ new_names[[ i ]] ]] <-floor((medie_i*1000-200)/ data_new2[[ cols_to_process[[ i ]] ]])
  
 
}
head(data_new2)
#>   Buc      MT   Kg Lung medie Pcs      CTT     util  V1  V2  V3  V4  V5  V6  V7
#> 1 302 1884.48 2619  184  6.24  32 1.059783 1778.176 216 213 216 213 216 216 184
#> 2 296 1847.40 2568  216  6.24  27 1.070167 1726.272 216 184 213 184 184 184 216
#> 3 304 1869.96 2599  216  6.15  27 1.054730 1772.928 216 184 213 184 216 184 213
#> 4 240 1497.60 2082  184  6.24  32 1.059783 1413.120 216 213 184 216 216 184 216
#> 5 385 2194.50 3050  216  5.70  25 1.055556 2079.000 213 213 216 216 213 216 213
#> 6 302 1887.50 2624  184  6.25  32 1.061481 1778.176 213 213 213 184 213 216 213
#>    V8  V9 V10 W1 W2 W3 W4 W5 W6 W7 W8 W9 W10
#> 1 184 184 216 27 28 27 28 25 28 32 32 32  28
#> 2 213 216 213 27 32 27 32 29 32 28 28 27  28
#> 3 213 184 184 27 32 27 32 25 32 28 28 32  33
#> 4 216 213 216 27 28 32 27 25 32 28 28 27  28
#> 5 216 216 216 28 28 27 27 25 28 28 28 27  28
#> 6 213 184 213 28 28 27 32 25 28 28 28 32  28
(colnames <- colnames(data_new2))
#>  [1] "Buc"   "MT"    "Kg"    "Lung"  "medie" "Pcs"   "CTT"   "util"  "V1"   
#> [10] "V2"    "V3"    "V4"    "V5"    "V6"    "V7"    "V8"    "V9"    "V10"  
#> [19] "W1"    "W2"    "W3"    "W4"    "W5"    "W6"    "W7"    "W8"    "W9"   
#> [28] "W10"


(cols_to_process <-colnames( data_new2 %>% select(V1:W10)))
#>  [1] "V1"  "V2"  "V3"  "V4"  "V5"  "V6"  "V7"  "V8"  "V9"  "V10" "W1"  "W2" 
#> [13] "W3"  "W4"  "W5"  "W6"  "W7"  "W8"  "W9"  "W10"
(new_names <- sub("^W", "x", cols_to_process))
#>  [1] "V1"  "V2"  "V3"  "V4"  "V5"  "V6"  "V7"  "V8"  "V9"  "V10" "x1"  "x2" 
#> [13] "x3"  "x4"  "x5"  "x6"  "x7"  "x8"  "x9"  "x10"
for(i in seq_along(cols_to_process)){
  V_i<-data_new2$V[[i]]
    W_i<-data_new2$W[[i]]
  Buc_i<-data_new2$Buc[[i]]
    data_new2[[ new_names[[ i ]] ]] <-Buc_i *data_new2[[ cols_to_process[[ i ]] ]]
  
 
}
head(data_new2)
#>   Buc      MT   Kg Lung medie Pcs      CTT     util    V1    V2    V3    V4
#> 1 302 1884.48 2619  184  6.24  32 1.059783 1778.176 65232 63048 65664 51120
#> 2 296 1847.40 2568  216  6.24  27 1.070167 1726.272 65232 54464 64752 44160
#> 3 304 1869.96 2599  216  6.15  27 1.054730 1772.928 65232 54464 64752 44160
#> 4 240 1497.60 2082  184  6.24  32 1.059783 1413.120 65232 63048 55936 51840
#> 5 385 2194.50 3050  216  5.70  25 1.055556 2079.000 64326 63048 65664 51840
#> 6 302 1887.50 2624  184  6.25  32 1.061481 1778.176 64326 63048 64752 44160
#>      V5    V6    V7    V8    V9   V10 W1 W2 W3 W4 W5 W6 W7 W8 W9 W10   x1    x2
#> 1 83160 65232 59248 56304 65688 63720 27 28 27 28 25 28 32 32 32  28 8640  8820
#> 2 70840 55568 69552 65178 77112 62835 27 32 27 32 29 32 28 28 27  28 8640 10080
#> 3 83160 55568 68586 65178 65688 54280 27 32 27 32 25 32 28 28 32  33 8640 10080
#> 4 83160 55568 69552 66096 76041 63720 27 28 32 27 25 32 28 28 27  28 8640  8820
#> 5 82005 65232 68586 66096 77112 63720 28 28 27 27 25 28 28 28 27  28 8960  8820
#> 6 82005 65232 68586 65178 65688 62835 28 28 27 32 25 28 28 28 32  28 8960  8820
#>     x3   x4   x5    x6   x7   x8   x9  x10
#> 1 5886 7560 7000 10080 9216 9408 9856 7924
#> 2 5886 8640 8120 11520 8064 8232 8316 7924
#> 3 5886 8640 7000 11520 8064 8232 9856 9339
#> 4 6976 7290 7000 11520 8064 8232 8316 7924
#> 5 5886 7290 7000 10080 8064 8232 8316 7924
#> 6 5886 8640 7000 10080 8064 8232 9856 7924
#############

Created on 2024-04-06 with reprex v2.0.2

This is unrelated to your original topic — is there a reason you posted it here?

From the sessionInfo() output you posted here, I don't think you can use the base R pipe (|>) or the \(input) output version of anonymous functions, so you would want to try this instead:

df <- 
  data.frame(
    A = c(12,71,53,34,21),
    B = c(23, 41, 32, 58, 26),
    C = c(12,1,3,5,6),
    D = c(12,4,7,8,11),
    E = c(11,33,45,67,89)
  )

df
#>    A  B  C  D  E
#> 1 12 23 12 12 11
#> 2 71 41  1  4 33
#> 3 53 32  3  7 45
#> 4 34 58  5  8 67
#> 5 21 26  6 11 89
library(tidyverse)

# applying to each column, without changing column names
df %>%
  # using anonymous function of the form '~ output', where 'output' is 
  # the result of transforming the input, which is represented by '.'
  mutate(
    across(
      B:E, 
      ~ A - .
    )
  )
#>    A   B  C  D   E
#> 1 12 -11  0  0   1
#> 2 71  30 70 67  38
#> 3 53  21 50 46   8
#> 4 34 -24 29 26 -33
#> 5 21  -5 15 10 -68

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.