Vprašanje

… napisal sem čisto preprosto funkcijo, vendar bi rad videl, da bi bil output zapisan v obstoječ dataframe, oz. da bi prepisal že obstoječi stolpec. to pa mi nikakor ne uspe. spodaj je primer kode in podatkovja.

same_picking <- function(cena){
  data_model2$price_model2 <- 0.6 + cena * data_model2$item_SKU + 0.4
}
count_code  sifra   item_SKU    price_model2
281         0421    2           NA
683         0499    5           NA
903         0654    3           NA
7390        0942    3           NA
2778        0796    5           NA
2778        0796    7           NA
7066        0907    83          NA
281         0421    2           NA

Testni podatki

data <- as.data.frame(matrix(c(281, 0421, 2, NA,
683, 0499, 5, NA,
903, 0654, 3, NA,
7390, 0942, 3, NA,
2778, 0796, 5, NA,
2778, 0796, 7, NA,
7066, 0907, 83, NA,
281, 0421, 2, NA),byrow=TRUE,ncol=4))
names(data) <- c("count_code", "sifra", "item_SKU", "price_model2")
data
##   count_code sifra item_SKU price_model2
## 1        281   421        2           NA
## 2        683   499        5           NA
## 3        903   654        3           NA
## 4       7390   942        3           NA
## 5       2778   796        5           NA
## 6       2778   796        7           NA
## 7       7066   907       83           NA
## 8        281   421        2           NA

Odgovor

Funkcija vzame kot argument objekt cena, ki je tako edini objek, ki obstaja ZNOTRAJ funkcije. Objekt, v katerega skušate napisati rezultate je ZUNAJ funkcije, in ga funkcija vidi v svoji okolici (v Environment oz. Work space). Ta (znotraj/zunaj) je znan kot scope.

Imamo več možnosti:

1. Prirejanje neposredno vzunanji objekt (Environment)

Če hočemo spreminjati objekt, ki je zunaj funkcije uporabimo prireditveni znak <<- (dvojna puščica), ki zadene tudi zunanjost. S tem spremenimo vrednosti v zunanjem objektu.

(data_model2 <- data)
##   count_code sifra item_SKU price_model2
## 1        281   421        2           NA
## 2        683   499        5           NA
## 3        903   654        3           NA
## 4       7390   942        3           NA
## 5       2778   796        5           NA
## 6       2778   796        7           NA
## 7       7066   907       83           NA
## 8        281   421        2           NA
same_picking <- function(cena){
  data_model2$price_model2 <<- 0.6 + cena * data_model2$item_SKU + 0.4
}
same_picking(1)
data_model2
##   count_code sifra item_SKU price_model2
## 1        281   421        2            3
## 2        683   499        5            6
## 3        903   654        3            4
## 4       7390   942        3            4
## 5       2778   796        5            6
## 6       2778   796        7            8
## 7       7066   907       83           84
## 8        281   421        2            3

2. Prirejanje rezultata funkcije, ki uporablja zunanji objekt

Bolj v duhu ortodoksnega R pa naredimo tako, da funkcija sproducira rezulat, ki ga umestimo na primerno mesto:

(data_model2 <- data)
##   count_code sifra item_SKU price_model2
## 1        281   421        2           NA
## 2        683   499        5           NA
## 3        903   654        3           NA
## 4       7390   942        3           NA
## 5       2778   796        5           NA
## 6       2778   796        7           NA
## 7       7066   907       83           NA
## 8        281   421        2           NA
same_picking <- function(cena){
  res <- 0.6 + cena * data_model2$item_SKU + 0.4
}
data_model2$price_model2 <- same_picking(1)
data_model2
##   count_code sifra item_SKU price_model2
## 1        281   421        2            3
## 2        683   499        5            6
## 3        903   654        3            4
## 4       7390   942        3            4
## 5       2778   796        5            6
## 6       2778   796        7            8
## 7       7066   907       83           84
## 8        281   421        2            3

3. Funkcija, ki ni odvisna od zunanjih objektov

Še splošneje pa je, da funkcija ni odvisna od dejanskih imen objektov v zunanjosti

(data_model2 <- data)
##   count_code sifra item_SKU price_model2
## 1        281   421        2           NA
## 2        683   499        5           NA
## 3        903   654        3           NA
## 4       7390   942        3           NA
## 5       2778   796        5           NA
## 6       2778   796        7           NA
## 7       7066   907       83           NA
## 8        281   421        2           NA
same_picking <- function(cena, item){
  res <- 0.6 + cena * item + 0.4
}
data_model2$price_model2 <- same_picking(1, item = data_model2$item_SKU)
data_model2
##   count_code sifra item_SKU price_model2
## 1        281   421        2            3
## 2        683   499        5            6
## 3        903   654        3            4
## 4       7390   942        3            4
## 5       2778   796        5            6
## 6       2778   796        7            8
## 7       7066   907       83           84
## 8        281   421        2            3

4. Prirejanje novemu stolpcu

Še nekaj. Objektu vrste data.frame lahko dodate nov stolpec, ki še ni obstajal (vektor NA v četrtem stolpcu ni vnaprej potreben)

(data_model2 <- data)
##   count_code sifra item_SKU price_model2
## 1        281   421        2           NA
## 2        683   499        5           NA
## 3        903   654        3           NA
## 4       7390   942        3           NA
## 5       2778   796        5           NA
## 6       2778   796        7           NA
## 7       7066   907       83           NA
## 8        281   421        2           NA
same_picking <- function(cena, item){
  res <- 0.6 + cena * item + 0.4
}
data_model2$nov_price_model <- same_picking(2, item = data_model2$item_SKU)
data_model2
##   count_code sifra item_SKU price_model2 nov_price_model
## 1        281   421        2           NA               5
## 2        683   499        5           NA              11
## 3        903   654        3           NA               7
## 4       7390   942        3           NA               7
## 5       2778   796        5           NA              11
## 6       2778   796        7           NA              15
## 7       7066   907       83           NA             167
## 8        281   421        2           NA               5

Zaradi preglednosti in splošnosti priporočam možnosti 3. in 4., čeprav včasih ne gre brez preostalih dveh.