dplyr, satırların bir alt kümesindeki birkaç sütunu değiştirir / değiştirir


86

Dplyr tabanlı bir iş akışını deneme sürecindeyim (alışkın olduğum çoğunlukla data.table kullanmak yerine) ve eşdeğer bir dplyr çözümü bulamadığım bir sorunla karşılaştım . Genellikle, tek bir koşula bağlı olarak birkaç sütunu koşullu olarak güncellemem / değiştirmem gereken senaryo ile karşılaşıyorum. İşte data.table çözümümle birlikte bazı örnek kod:

library(data.table)

# Create some sample data
set.seed(1)
dt <- data.table(site = sample(1:6, 50, replace=T),
                 space = sample(1:4, 50, replace=T),
                 measure = sample(c('cfl', 'led', 'linear', 'exit'), 50, 
                               replace=T),
                 qty = round(runif(50) * 30),
                 qty.exit = 0,
                 delta.watts = sample(10.5:100.5, 50, replace=T),
                 cf = runif(50))

# Replace the values of several columns for rows where measure is "exit"
dt <- dt[measure == 'exit', 
         `:=`(qty.exit = qty,
              cf = 0,
              delta.watts = 13)]

Aynı problem için basit bir dplyr çözümü var mı? İfelse'yi kullanmaktan kaçınmak istiyorum çünkü koşulu birden çok kez yazmak zorunda kalmak istemiyorum - bu basitleştirilmiş bir örnektir, ancak bazen tek bir koşula dayalı birçok atama vardır.

Yardım için şimdiden teşekkürler!

Yanıtlar:


83

Bu çözeltiler (1) boru hattını korumak (2) do not girişi ve üzerine (3) tek koşul kez belirtilen gerektirir:

1a) mutate_cond İşlem hatlarına dahil edilebilecek veri çerçeveleri veya veri tabloları için basit bir işlev oluşturun. Bu işlev gibidir, mutateancak yalnızca koşulu sağlayan satırlar üzerinde çalışır:

mutate_cond <- function(.data, condition, ..., envir = parent.frame()) {
  condition <- eval(substitute(condition), .data, envir)
  .data[condition, ] <- .data[condition, ] %>% mutate(...)
  .data
}

DF %>% mutate_cond(measure == 'exit', qty.exit = qty, cf = 0, delta.watts = 13)

1b) mutate_last Bu, yine benzer olan mutateancak sadece içinde kullanılan group_by(aşağıdaki örnekte olduğu gibi) ve her gruptan ziyade yalnızca son grupta çalışan veri çerçeveleri veya veri tabloları için alternatif bir işlevdir . DOĞRU> YANLIŞ olduğuna dikkat edin, bu nedenle group_bybir koşul belirtirse mutate_last, yalnızca bu koşulu sağlayan satırlarda çalışacaktır.

mutate_last <- function(.data, ...) {
  n <- n_groups(.data)
  indices <- attr(.data, "indices")[[n]] + 1
  .data[indices, ] <- .data[indices, ] %>% mutate(...)
  .data
}


DF %>% 
   group_by(is.exit = measure == 'exit') %>%
   mutate_last(qty.exit = qty, cf = 0, delta.watts = 13) %>%
   ungroup() %>%
   select(-is.exit)

2) koşulu parantezin dışında bırakın Koşulu daha sonra kaldırılacak olan fazladan bir sütun yaparak parantezin dışında bırakın. Ardından ifelse, replacegösterildiği gibi mantıksallarla birlikte kullanın veya aritmetik. Bu aynı zamanda veri tabloları için de geçerlidir.

library(dplyr)

DF %>% mutate(is.exit = measure == 'exit',
              qty.exit = ifelse(is.exit, qty, qty.exit),
              cf = (!is.exit) * cf,
              delta.watts = replace(delta.watts, is.exit, 13)) %>%
       select(-is.exit)

3) sqldfupdate Veri çerçeveleri için boru hattındaki sqldf paketi aracılığıyla SQL kullanabiliriz (ancak bunları dönüştürmedikçe veri tablolarını kullanmayız - bu dplyr'de bir hata olabilir. Bkz. Dplyr sorunu 1579 ). Bu koddaki girdiyi istenmeyen bir şekilde değiştiriyormuşuz gibi görünebilir, updateancak aslında updategeçici olarak oluşturulan veritabanındaki girdinin bir kopyası üzerinde hareket ediyor ve asıl girdiye göre değil.

library(sqldf)

DF %>% 
   do(sqldf(c("update '.' 
                 set 'qty.exit' = qty, cf = 0, 'delta.watts' = 13 
                 where measure = 'exit'", 
              "select * from '.'")))

4) row_case_when Ayrıca kontrol row_case_whentanımlanan nasıl case_when ile vektörize: Bir Tibble dönersek? . case_whenSatırlara benzer ancak bunlar için geçerli olan bir sözdizimi kullanır .

library(dplyr)

DF %>%
  row_case_when(
    measure == "exit" ~ data.frame(qty.exit = qty, cf = 0, delta.watts = 13),
    TRUE ~ data.frame(qty.exit, cf, delta.watts)
  )

Not 1: Bunu şu şekilde kullandık :DF

set.seed(1)
DF <- data.frame(site = sample(1:6, 50, replace=T),
                 space = sample(1:4, 50, replace=T),
                 measure = sample(c('cfl', 'led', 'linear', 'exit'), 50, 
                               replace=T),
                 qty = round(runif(50) * 30),
                 qty.exit = 0,
                 delta.watts = sample(10.5:100.5, 50, replace=T),
                 cf = runif(50))

Not 2: kolayca satırların bir alt kümesini güncelleme belirtmek için nasıl bir sorun da dplyr konularda tartışılmıştır 134 , 631 , 1518 ve 1573 ile 631 ana iş parçacığı olma ve 1573 burada cevapları gözden olmak.


1
Mükemmel cevap, teşekkürler! Mutate_cond ve @Kevin Ushey'in mutate_when ikisi de bu soruna iyi çözümler olabilir. Sanırım mutate_when'in okunabilirliği / esnekliği konusunda küçük bir tercihim var, ancak bu yanıta tamlık için "kontrol" yapacağım.
Chris Newton

Mutate_cond yaklaşımını gerçekten seviyorum. Bana öyle geliyor ki, bu işlev veya ona çok yakın bir şey dplyr'e dahil edilmeyi hak ediyor ve insanların düşündüğü kullanım durumu için VectorizedSwitch'ten ( github.com/hadley/dplyr/issues/1573'te tartışılan ) daha iyi bir çözüm olabilir. burada ...
Magnus

Mutate_cond'ı seviyorum. Çeşitli seçenekler ayrı cevaplar olmalıydı.
Holger Brandl

Birkaç yıl oldu ve github sorunları kapalı ve kilitli görünüyor. Bu soruna resmi bir çözüm var mı?
static_rtti

27

Bunu magrittriki yönlü borusuyla yapabilirsiniz %<>%:

library(dplyr)
library(magrittr)

dt[dt$measure=="exit",] %<>% mutate(qty.exit = qty,
                                    cf = 0,  
                                    delta.watts = 13)

Bu, yazma miktarını azaltır, ancak yine de olduğundan çok daha yavaştır data.table.


Aslında, şimdi bunu test etme şansım olduğuna göre, dt [dt $ measure == 'exit',] gösterimini kullanarak alt küme ihtiyacını ortadan kaldıran bir çözümü tercih ederim, çünkü bu daha uzun süre kullanışsız hale gelebilir dt isimleri.
Chris Newton

Yalnızca bir Bilginize, ancak bu çözüm yalnızca data.frame/ tibbletarafından tanımlanan sütunu zaten içeriyorsa işe yarar mutate. Yeni bir sütun eklemeye çalışıyorsanız, örneğin ilk kez bir döngüden geçip a data.frame.
Ursus Frost

@UrsusFrost, veri kümesinin yalnızca bir alt kümesi olan yeni bir sütun eklemek bana garip geliyor. Alt kümelenmemiş satırlara NA ekler misiniz?
Baraliuh

@Baraliuh Evet, bunu takdir edebilirim. Verileri bir tarih listesine eklediğim ve artırdığım bir döngünün parçası. İlk birkaç tarih, gerçek dünyadaki iş süreçlerini kopyaladığı için sonraki tarihlerden farklı şekilde ele alınmalıdır. Daha sonraki yinelemelerde, tarihlerin koşullarına bağlı olarak veriler farklı şekilde hesaplanır. Koşullu olması nedeniyle, .pst dosyasındaki önceki tarihleri ​​yanlışlıkla değiştirmek istemiyorum data.frame. FWIW, data.tablebunun yerine kullanmaya geri döndüm dplyrçünkü iifadesi bunu kolayca hallediyor - artı genel döngü çok daha hızlı çalışıyor.
Ursus Frost

19

İşte sevdiğim bir çözüm:

mutate_when <- function(data, ...) {
  dots <- eval(substitute(alist(...)))
  for (i in seq(1, length(dots), by = 2)) {
    condition <- eval(dots[[i]], envir = data)
    mutations <- eval(dots[[i + 1]], envir = data[condition, , drop = FALSE])
    data[condition, names(mutations)] <- mutations
  }
  data
}

Örneğin,

mtcars %>% mutate_when(
  mpg > 22,    list(cyl = 100),
  disp == 160, list(cyl = 200)
)

ki bu oldukça okunabilir - her ne kadar olabileceği kadar performanslı olmasa da.


14

Eipi10'un yukarıda gösterdiği gibi, dplyr'de alt küme değişimi yapmanın basit bir yolu yoktur, çünkü DT, geçiş-değer kullanarak dplyr yerine referansla geçiş semantiğini kullanır. dplyr ifelse(), tüm vektör üzerinde ' nin kullanılmasını gerektirir , oysa DT alt kümeyi yapar ve referansa göre günceller (tüm DT'yi döndürür). Dolayısıyla, bu alıştırma için DT önemli ölçüde daha hızlı olacaktır.

Alternatif olarak önce alt küme, ardından güncelleme ve son olarak yeniden birleştirebilirsiniz:

dt.sub <- dt[dt$measure == "exit",] %>%
  mutate(qty.exit= qty, cf= 0, delta.watts= 13)

dt.new <- rbind(dt.sub, dt[dt$measure != "exit",])

Ancak DT çok daha hızlı olacak: (eipi10'un yeni cevabını kullanacak şekilde düzenlendi)

library(data.table)
library(dplyr)
library(microbenchmark)
microbenchmark(dt= {dt <- dt[measure == 'exit', 
                            `:=`(qty.exit = qty,
                                 cf = 0,
                                 delta.watts = 13)]},
               eipi10= {dt[dt$measure=="exit",] %<>% mutate(qty.exit = qty,
                                cf = 0,  
                                delta.watts = 13)},
               alex= {dt.sub <- dt[dt$measure == "exit",] %>%
                 mutate(qty.exit= qty, cf= 0, delta.watts= 13)

               dt.new <- rbind(dt.sub, dt[dt$measure != "exit",])})


Unit: microseconds
expr      min        lq      mean   median       uq      max neval cld
     dt  591.480  672.2565  747.0771  743.341  780.973 1837.539   100  a 
 eipi10 3481.212 3677.1685 4008.0314 3796.909 3936.796 6857.509   100   b
   alex 3412.029 3637.6350 3867.0649 3726.204 3936.985 5424.427   100   b

10

Sadece buna rastladım ve mutate_cond()@G'den gerçekten hoşlandım . Grothendieck, ancak yeni değişkenlerle başa çıkmanın da kullanışlı olabileceğini düşündü. Yani, aşağıda iki ekleme var:

İlgisiz: İkinci geçen çizgi daha biraz yapılmış dplyrkullanarakfilter()

Başlangıçtaki üç yeni satır, içinde kullanılmak üzere değişken adlarını alır mutate()ve mutate()oluşmadan önce veri çerçevesindeki yeni değişkenleri başlatır . data.frameKullanmanın geri kalanı için yeni değişkenler başlatılır ve varsayılan olarak new_initmissing ( NA) olarak ayarlanır .

mutate_cond <- function(.data, condition, ..., new_init = NA, envir = parent.frame()) {
  # Initialize any new variables as new_init
  new_vars <- substitute(list(...))[-1]
  new_vars %<>% sapply(deparse) %>% names %>% setdiff(names(.data))
  .data[, new_vars] <- new_init

  condition <- eval(substitute(condition), .data, envir)
  .data[condition, ] <- .data %>% filter(condition) %>% mutate(...)
  .data
}

İşte iris verilerini kullanan bazı örnekler:

Petal.Length88 olarak değiştir Species == "setosa". Bu, orijinal işlevde ve bu yeni sürümde çalışacaktır.

iris %>% mutate_cond(Species == "setosa", Petal.Length = 88)

Yukarıdakinin aynısı, ancak aynı zamanda yeni bir değişken oluşturun x( NAkoşula dahil olmayan satırlarda). Daha önce mümkün değil.

iris %>% mutate_cond(Species == "setosa", Petal.Length = 88, x = TRUE)

Yukarıdakinin aynısı, ancak koşuluna dahil olmayan satırlar xYANLIŞ olarak ayarlandı.

iris %>% mutate_cond(Species == "setosa", Petal.Length = 88, x = TRUE, new_init = FALSE)

Bu örnek, farklı değerlerle birden çok yeni değişkeni başlatmak new_initiçin nasıl a olarak ayarlanabileceğini gösterir list. Burada, iki yeni değişkenler (farklı değerler kullanılarak başlatıldı dışlanan satırlarla oluşturulur xolarak başlatıldı FALSE, ysıra NA)

iris %>% mutate_cond(Species == "setosa" & Sepal.Length < 5,
                  x = TRUE, y = Sepal.Length ^ 2,
                  new_init = list(FALSE, NA))

Sizin mutate_condişlevi benim veri kümesi üzerinde bir hata trows ve Grothendiecks' çalışmaz. Error: incorrect length (4700), expecting: 168Filtre işleviyle ilişkili görünüyor.
RHA

Bunu bir kütüphaneye mi koydunuz veya bir işlev olarak resmileştirdiniz mi? Özellikle tüm iyileştirmelerle, beyinsiz gibi görünüyor.
Nettle

1
Hayır. Şu anda dplyr ile en iyi yaklaşımın mutasyonu if_elseveya ile birleştirmek olduğunu düşünüyorum case_when.
Simon Jackson

Bu yaklaşıma bir örnek (veya bağlantı) verebilir misiniz?
Isırgan

6

mutate_cond harika bir işlevdir, ancak koşulu oluşturmak için kullanılan sütun (lar) da NA varsa hata verir. Koşullu bir mutatın bu tür sıraları rahat bırakması gerektiğini düşünüyorum. Bu, koşul TRUE olduğunda satırları döndüren, ancak her iki satırı da FALSE ve NA ile atlayan filter () davranışıyla eşleşir.

Bu küçük değişiklikle işlev bir cazibe gibi çalışır:

mutate_cond <- function(.data, condition, ..., envir = parent.frame()) {
    condition <- eval(substitute(condition), .data, envir)
    condition[is.na(condition)] = FALSE
    .data[condition, ] <- .data[condition, ] %>% mutate(...)
    .data
}

Teşekkürler Magnus! Bunu, bir animasyonu oluşturan tüm nesnelerin eylemlerini ve zamanlamalarını içeren bir tabloyu güncellemek için kullanıyorum. NA sorununa çarptım çünkü veriler o kadar çeşitli ki bazı eylemler bazı nesneler için anlam ifade etmiyor, bu yüzden bu hücrelerde NA'lar var. Yukarıdaki diğer mutate_cond düştü, ancak çözümünüz bir cazibe gibi çalıştı.
Phil van Kleur

Bu sizin için yararlıysa, bu işlev yazdığım "zulutils" adlı küçük bir pakette mevcuttur. CRAN'da değil ama uzaktan kumandaları kullanarak kurabilirsiniz :: install_github ("torfason / zulutils")
Magnus

4

Aslında dplyrbunu çok daha kolay hale getirecek herhangi bir değişiklik görmüyorum . case_whenbir sütun için birden çok farklı koşul ve sonuç olduğunda harikadır, ancak bir koşula göre birden çok sütunu değiştirmek istediğiniz bu durumda yardımcı olmaz. Benzer şekilde, recodebir sütunda birden çok farklı değeri değiştiriyorsanız, ancak bunu aynı anda birden çok sütunda yapmanıza yardımcı olmuyorsa yazmayı kaydeder. Son olarak, mutate_atvs., veri çerçevesindeki satırlara değil, yalnızca sütun adlarına koşullar uygular. Mutate_at için potansiyel olarak bunu yapacak bir işlev yazabilirsiniz, ancak farklı sütunlar için nasıl farklı davranmasını sağlayacağınızı çözemiyorum.

Yani burada söz konusu o kullanarak yaklaşım şekli şöyledir nestformu tidyrve mapgelen purrr.

library(data.table)
library(dplyr)
library(tidyr)
library(purrr)

# Create some sample data
set.seed(1)
dt <- data.table(site = sample(1:6, 50, replace=T),
                 space = sample(1:4, 50, replace=T),
                 measure = sample(c('cfl', 'led', 'linear', 'exit'), 50, 
                                  replace=T),
                 qty = round(runif(50) * 30),
                 qty.exit = 0,
                 delta.watts = sample(10.5:100.5, 50, replace=T),
                 cf = runif(50))

dt2 <- dt %>% 
  nest(-measure) %>% 
  mutate(data = if_else(
    measure == "exit", 
    map(data, function(x) mutate(x, qty.exit = qty, cf = 0, delta.watts = 13)),
    data
  )) %>%
  unnest()

1
Önereceğim tek şey nest(-measure), kaçınmak için kullanmakgroup_by
Dave Gruenewald

@DaveGruenewald önerisini yansıtacak şekilde düzenlendi
bkz. 24

4

Kısa bir çözüm, filtrelenmiş alt kümede mutasyonu yapmak ve ardından tablonun çıkış olmayan satırlarını geri eklemek olabilir:

library(dplyr)

dt %>% 
    filter(measure == 'exit') %>%
    mutate(qty.exit = qty, cf = 0, delta.watts = 13) %>%
    rbind(dt %>% filter(measure != 'exit'))

3

Oluşturulduğunda, rlangGrothendieck'in 1a örneğinin biraz değiştirilmiş bir versiyonu mümkündür, otomatik olarak oluşturulan ortamı yakaladığı için envirargüman ihtiyacını ortadan kaldırır .enquo().p

mutate_rows <- function(.data, .p, ...) {
  .p <- rlang::enquo(.p)
  .p_lgl <- rlang::eval_tidy(.p, .data)
  .data[.p_lgl, ] <- .data[.p_lgl, ] %>% mutate(...)
  .data
}

dt %>% mutate_rows(measure == "exit", qty.exit = qty, cf = 0, delta.watts = 13)

2

Veri setini bölebilir ve TRUEparça üzerinde düzenli bir değişim çağrısı yapabilirsiniz .

dplyr 0.8group_split , gruplara ayrılan (ve gruplar doğrudan çağrıda tanımlanabilen) bir işleve sahiptir, bu nedenle burada kullanacağız, ancak base::splitaynı zamanda çalışıyor.

library(tidyverse)
df1 %>%
  group_split(measure == "exit", keep=FALSE) %>% # or `split(.$measure == "exit")`
  modify_at(2,~mutate(.,qty.exit = qty, cf = 0, delta.watts = 13)) %>%
  bind_rows()

#    site space measure qty qty.exit delta.watts          cf
# 1     1     4     led   1        0        73.5 0.246240409
# 2     2     3     cfl  25        0        56.5 0.360315879
# 3     5     4     cfl   3        0        38.5 0.279966850
# 4     5     3  linear  19        0        40.5 0.281439486
# 5     2     3  linear  18        0        82.5 0.007898384
# 6     5     1  linear  29        0        33.5 0.392412729
# 7     5     3  linear   6        0        46.5 0.970848817
# 8     4     1     led  10        0        89.5 0.404447182
# 9     4     1     led  18        0        96.5 0.115594622
# 10    6     3  linear  18        0        15.5 0.017919745
# 11    4     3     led  22        0        54.5 0.901829577
# 12    3     3     led  17        0        79.5 0.063949974
# 13    1     3     led  16        0        86.5 0.551321441
# 14    6     4     cfl   5        0        65.5 0.256845013
# 15    4     2     led  12        0        29.5 0.340603733
# 16    5     3  linear  27        0        63.5 0.895166931
# 17    1     4     led   0        0        47.5 0.173088800
# 18    5     3  linear  20        0        89.5 0.438504370
# 19    2     4     cfl  18        0        45.5 0.031725246
# 20    2     3     led  24        0        94.5 0.456653397
# 21    3     3     cfl  24        0        73.5 0.161274319
# 22    5     3     led   9        0        62.5 0.252212124
# 23    5     1     led  15        0        40.5 0.115608182
# 24    3     3     cfl   3        0        89.5 0.066147321
# 25    6     4     cfl   2        0        35.5 0.007888337
# 26    5     1  linear   7        0        51.5 0.835458916
# 27    2     3  linear  28        0        36.5 0.691483644
# 28    5     4     led   6        0        43.5 0.604847889
# 29    6     1  linear  12        0        59.5 0.918838163
# 30    3     3  linear   7        0        73.5 0.471644760
# 31    4     2     led   5        0        34.5 0.972078100
# 32    1     3     cfl  17        0        80.5 0.457241602
# 33    5     4  linear   3        0        16.5 0.492500255
# 34    3     2     cfl  12        0        44.5 0.804236607
# 35    2     2     cfl  21        0        50.5 0.845094268
# 36    3     2  linear  10        0        23.5 0.637194873
# 37    4     3     led   6        0        69.5 0.161431896
# 38    3     2    exit  19       19        13.0 0.000000000
# 39    6     3    exit   7        7        13.0 0.000000000
# 40    6     2    exit  20       20        13.0 0.000000000
# 41    3     2    exit   1        1        13.0 0.000000000
# 42    2     4    exit  19       19        13.0 0.000000000
# 43    3     1    exit  24       24        13.0 0.000000000
# 44    3     3    exit  16       16        13.0 0.000000000
# 45    5     3    exit   9        9        13.0 0.000000000
# 46    2     3    exit   6        6        13.0 0.000000000
# 47    4     1    exit   1        1        13.0 0.000000000
# 48    1     1    exit  14       14        13.0 0.000000000
# 49    6     3    exit   7        7        13.0 0.000000000
# 50    2     4    exit   3        3        13.0 0.000000000

Satır sırası konularda, kullanmak tibble::rowid_to_column, sonra ilk dplyr::arrangeon rowidve sonunda dışarı seçin.

veri

df1 <- data.frame(site = sample(1:6, 50, replace=T),
                 space = sample(1:4, 50, replace=T),
                 measure = sample(c('cfl', 'led', 'linear', 'exit'), 50, 
                                  replace=T),
                 qty = round(runif(50) * 30),
                 qty.exit = 0,
                 delta.watts = sample(10.5:100.5, 50, replace=T),
                 cf = runif(50),
                 stringsAsFactors = F)

2

Sanırım bu cevaba daha önce değinilmedi. Neredeyse 'varsayılan' çözüm kadar hızlı çalışır data.table..

Kullanım base::replace()

df %>% mutate( qty.exit = replace( qty.exit, measure == 'exit', qty[ measure == 'exit'] ),
                          cf = replace( cf, measure == 'exit', 0 ),
                          delta.watts = replace( delta.watts, measure == 'exit', 13 ) )

replace, değiştirme değerini geri dönüştürür, bu nedenle sütunların değerlerinin sütunlara qtygirilmesini istediğinizde, aynı zamanda qty.exitalt küme yapmanız gerekir qty... dolayısıyla qty[ measure == 'exit']ilk değiştirmede ..

şimdi, muhtemelen measure == 'exit'her zaman yeniden yazmak istemeyeceksiniz ... böylece bu seçimi içeren bir indeks vektörü oluşturabilir ve onu yukarıdaki işlevlerde kullanabilirsiniz.

#build an index-vector matching the condition
index.v <- which( df$measure == 'exit' )

df %>% mutate( qty.exit = replace( qty.exit, index.v, qty[ index.v] ),
               cf = replace( cf, index.v, 0 ),
               delta.watts = replace( delta.watts, index.v, 13 ) )

kıyaslamalar

# Unit: milliseconds
#         expr      min       lq     mean   median       uq      max neval
# data.table   1.005018 1.053370 1.137456 1.112871 1.186228 1.690996   100
# wimpel       1.061052 1.079128 1.218183 1.105037 1.137272 7.390613   100
# wimpel.index 1.043881 1.064818 1.131675 1.085304 1.108502 4.192995   100

1

Her zamanki dplyr sözdizimini bozmak pahasına, temelden kullanabilirsiniz within:

dt %>% within(qty.exit[measure == 'exit'] <- qty[measure == 'exit'],
              delta.watts[measure == 'exit'] <- 13)

Boruyla iyi bir şekilde bütünleşiyor gibi görünüyor ve içinde istediğiniz her şeyi yapabilirsiniz.


Bu yazıldığı gibi çalışmıyor çünkü ikinci ödev aslında gerçekleşmiyor. Ama yaparsanız dt %>% within({ delta.watts[measure == 'exit'] <- 13 ; qty.exit[measure == 'exit'] <- qty[measure == 'exit'] ; cf[measure == 'exit'] <- 0 })işe yarıyor
bkz. 24
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.