Я пытаюсь создать новые поля из df на основе совпадения условий. Ниже приведен df, который я пытаюсь использовать.

abc<- tibble::tribble(
  ~type,               ~match_type, ~count,
  "type b", "alpha",           2,
  "type a", "alpha",           4,
  "type b",           "alpha",           1,
  "type a",           "alpha",           2,
  "type a",    "beta",          32,
  "type a",    "beta",          40,
  "type a",    "beta",          39,
  "type a",    "beta",          40,
  "type a",    "beta",          55,
  "type b",    "beta",          66,
  "type b",    "beta",          35,
  "type b",    "beta",          72,
  "type b",    "beta",          54,
  "type b",    "beta",          30,
  "type b",    "beta",          22,
  "type b",    "beta",          24,
  "type b",    "beta",          13,
  "type b",    "beta",          32,
  "type b",    "beta",          18,
  "type b",    "beta",          40
)

Теперь, если match_type равно alpha, тогда создайте новое поле с именем альфа и просуммируйте там числа счетчика и аналогично для бета.

Это то, что я пробовал до сих пор, и ошибка, которую я получаю.

abc %>%  mutate(alpha=(count[match_type =="alpha"]),
                beta=(count[match_type =="beta"]))

Error: `mutate()` argument `alpha` must be recyclable.
ℹ `alpha` is `(count[match_type == "alpha"])`.
x `alpha` can't be recycled to size 20.
ℹ `alpha` must be size 20 or 1, not 4.

Я пытаюсь создать новый df, подобный этому (в этом примере числа могут не складываться)

result <- tibble::tribble(
  ~type,               ~alpha, ~beta,
  "type b", 22,           2,
  "type a", 12,           4
)

Как только я получу это выше df, я хочу вставить эти значения в этот фрейм данных на основе поля type, которое на данный момент равно na.

final_df <-tibble::tribble(
  ~type,               ~alpha, ~beta, val1 ,val2,
  "type b", na,           na, 4,5,
  "type a", na,           na,3,2,
  "type c", 22,           2,2,3,
  "type d", 12,           4,12,12,
  "type e", 22,           2,4,5,
  "type f", 12,           4,3,4
)

Я делаю слишком много шагов. есть простой способ сделать это. Спасибо

1
SNT 15 Апр 2020 в 00:29

1 ответ

Лучший ответ

Если нам нужен sum и мы хотим изменить его форму, используйте pivot_wider, а затем выполните right_join с 'final_fd' и coalesce столбцами 'alpha', 'beta' ( предполагая, что na равно NA)

library(dplyr)
library(tidyr)
abc %>% 
  pivot_wider(names_from = match_type, values_from = count, 
         values_fn = list(count = sum)) %>%
  right_join(final_df, by = 'type') %>%
  transmute(type, alpha = coalesce(alpha.y, alpha.x), 
       beta = coalesce(beta.y, beta.x), val1, val2)
# A tibble: 6 x 5
#  type   alpha  beta  val1  val2
#  <chr>  <dbl> <dbl> <dbl> <dbl>
#1 type b     3   406     4     5
#2 type a     6   206     3     2
#3 type c    22     2     2     3
#4 type d    12     4    12    12
#5 type e    22     2     4     5
#6 type f    12     4     3     4

Или используя data.table, сделайте join после преобразования формата abc в широкий с помощью dcast

library(data.table)
setDT(final_df)[dcast(setDT(abc), type ~ match_type, 
   value.var = 'count', sum), c('alpha','beta') := 
        .(i.alpha, i.beta), on = .(type)]

Данные

final_df <- structure(list(type = c("type b", "type a", "type c", "type d", 
"type e", "type f"), alpha = c(NA, NA, 22, 12, 22, 12), beta = c(NA, 
NA, 2, 4, 2, 4), val1 = c(4, 3, 2, 12, 4, 3), val2 = c(5, 2, 
3, 12, 5, 4)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
"data.frame"))
1
akrun 14 Апр 2020 в 21:49