У меня есть данные, которые выглядят так.

   investor_name funding_round_type count
   <chr>         <chr>              <int>
 1 .406 Ventures angel                  1
 2 .406 Ventures other                  2
 3 .406 Ventures private-equity         1
 4 .406 Ventures series-a               5
 5 .406 Ventures series-b               2
 6 .406 Ventures series-c+              7
 7 .406 Ventures venture                1
 8 500 Startups  angel                 40

Я хотел бы заменить все случаи, где funding_round_type равен venture, и заменить его на series-a, series-b или series-c+. Я бы хотел случайным образом выбрать один из них с вероятностью 40% для одного из первых двух и 20% для последнего.

my_df %>% 
   mutate(funding_round_type = ifelse(funding_round_type == "venture", 
                                      sample(c("series-a", "series-b", "series-c"), 1, replace = TRUE, prob = c(.4, .4, .2)),
                                      funding_round_type))

Как ни странно, sample(), кажется, выбирает один раз, а затем возвращается к выбранному значению для каждой строки. Я запускал это несколько раз, и он заменяет venture только одним из значений из моего списка параметров и не включает в себя экземпляры каких-либо других значений.

Как я могу заставить sample () работать заново в каждой строке?

r
2
tadon11Aaa 3 Май 2019 в 04:52

3 ответа

Лучший ответ

Это потому, что ifelse запускает функцию sample только один раз, и вы выбираете из нее одно значение, которое повторно используется для каждого другого значения. Попробуй сделать

library(dplyr)

my_df %>% 
  mutate(funding_round_type = ifelse(funding_round_type == "venture", 
        sample(c("series-a", "series-b", "series-c"), 
        sum(funding_round_type == "venture"),replace = TRUE, prob = c(.4, .4, .2)), 
        funding_round_type))

Или с replace

my_df %>% 
   mutate(funding_round_type = replace(funding_round_type, 
   funding_round_type == "venture", sample(c("series-a", "series-b", "series-c"), 
   sum(funding_round_type == "venture"), replace = TRUE, prob = c(.4, .4, .2))))

Также вы можете заменить это напрямую, без ifelse или каких-либо пакетов.

my_df$funding_round_type[my_df$funding_round_type == "venture"] <-  
    with(my_df, sample(c("series-a", "series-b", "series-c"), 
    sum(funding_round_type == "venture"), replace = TRUE, prob = c(.4, .4, .2)))
2
Ronak Shah 3 Май 2019 в 02:28

Использование rowwise() приведет к повторной выборке для каждой строки:

df %>%
  rowwise %>%
  mutate(funding_round_type = if_else(
    funding_round_type == "venture",
    sample(c("series-a", "series-b", "series-c+"), 1, prob = c(.4, .4, .2)),
    funding_round_type))

Также - второстепенный, но вам не нужен replace=TRUE, так как вы тянете только одну выборку за вызов к sample().

0
andrew_reece 3 Май 2019 в 02:09

Мы можем использовать data.table методы

library(data.table)
setDT(df)[funding_round_type == "venture", funding_round_type := 
    sample(c("series-a", "series-b", "series-c+"), 1, prob = c(.4, .4, .2))][]
#    investor_name funding_round_type count
#1: .406 Ventures              angel     1
#2: .406 Ventures              other     2
#3: .406 Ventures     private-equity     1
#4: .406 Ventures           series-a     5
#5: .406 Ventures           series-b     2
#6: .406 Ventures          series-c+     7
#7: .406 Ventures           series-b     1
#8:  500 Startups              angel    40

Или используя case_when из tidyverse

library(tidyerse)
df %>%
     mutate(funding_round_type = case_when(funding_round_type == "venture" ~ 
        sample(c("series-a", "series-b", "series-c+"), 1, prob = c(.4, .4, .2)),
       TRUE ~ funding_round_type))
#  investor_name funding_round_type count
#1 .406 Ventures              angel     1
#2 .406 Ventures              other     2
#3 .406 Ventures     private-equity     1
#4 .406 Ventures           series-a     5
#5 .406 Ventures           series-b     2
#6 .406 Ventures          series-c+     7
#7 .406 Ventures           series-a     1
#8  500 Startups              angel    40

Данные

df <- structure(list(investor_name = c(".406 Ventures", ".406 Ventures", 
".406 Ventures", ".406 Ventures", ".406 Ventures", ".406 Ventures", 
".406 Ventures", "500 Startups"), funding_round_type = c("angel", 
"other", "private-equity", "series-a", "series-b", "series-c+", 
"venture", "angel"), count = c(1L, 2L, 1L, 5L, 2L, 7L, 1L, 40L
)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", 
"6", "7", "8"))
0
akrun 3 Май 2019 в 03:12