Vytvoření funkce pro kontrolu kódy proti hlavní seznam

0

Otázka

Snažím se vytvořit vlastní funkci, která nejsem moc zkušený s tím, že by se zaškrtněte sloupec, který se skládá z položky kódy proti hlavní seznam. Pak bych rád (pokud je to možné) pro následující kroky, aby se stalo:

  • Vytvořit nový sloupec založen na seznamu (viz níže)
  • Naplnit sloupec s hodnotou (vynaložit), spojené s kód položky
  • Případně zkontrolujte, zda binární proměnnou a vzhledem k tomu, jednou z podmínek, odeslat hodnotu pro třetí sloupec

Seznam je druh vnořené kategorické seskupení, která vypadá jako tohle

code_list <- list((category_1 <- c("101", "102")), (category_2 <- c("201", "202", "203")))

Formátovaný jako že asi 70 "kategorie" Kódy, které mají být kontrolovány, jsou kódy jsou uloženy v "category_" hodnoty. V současné době mám kód, který pracuje v ifelse v mutate funkce, ale kód je neefektivní a není snadno upravit. Vypadá to, že:

mutate(category_2 = ifelse(code %in% category_2, value, 0), ...)

asi 60 řádků.

Mé otázky jsou-li funkce, jako je to vůbec možné, a pokud ano, jaké prostředky by mohly být špičaté, aby mě začal?

EDIT:

Můj pokus příklad

table <- data.frame('id' = c("1001", "1002", "1003", "1004", "1005"), 
    'bin' = c("0", "0", "1", "1", "0"),
    'expend' = c(111, 222, 333, 444, 555),
    'code' = c("101", "102", "201", "202", "102")
    )

code_list <- list(
    (category_1 <- c("101", "102")),
    (category_2 <- c("201", "202", "203"))
    )

table2 <- table %>%
    mutate(
    category_1 = ifelse(code %in% category_1, expend, 0),
    category_2 = ifelse(code %in% category_2, expend, 0)
    )

Ale mutate blok jde na, pro 60+ linky. V podstatě bych chtěl automatizovat mutate / ifelse funkce s výkonem jako

#     id bin expend code category_1 category_2
# 1 1001   0    111  101        111          0
# 2 1002   0    222  102        222          0
# 3 1003   1    333  201          0        333
# 4 1004   1    444  202          0        444
# 5 1005   0    555  102        555          0
dplyr r
2021-11-23 20:18:55
1

Nejlepší odpověď

0

Tady je možné řešení v tidyverse:

Řešení

library(tidyverse)


# ...
# Code to generate 'code_list' and 'table'.
# ...


# Turn the list into a table:
code_table <- code_list %>%
  # Force into a table with list columns.
  enframe() %>%
  # Unnest those list columns and pivot them into a long format:
  # 'name' | 'value'
  unnest_longer(value, indices_include = TRUE) %>%
  # Pivot those long columns into a wide format, with blanks (NA) for missing values:
  # 'category_1' | 'category_2' | ...
  pivot_wider() %>% select(!value_id)

# Mesh the results into a single table and perform logic.
result <- table %>%
  # Do a CROSS JOIN.
  full_join(
    code_table,
    by = character()
  ) %>%
  # Operate within the scope of each record from the original 'table'.
  group_by(id) %>%
  # Perform logic to "roll up" each scope into a single row.
  summarize(
    # Preserve each record from the original table...
    across(
      # ...namely everything except the 'category_*' columns.
      !c(starts_with("category_")),
      first
    ),

    # Then hit ALL 'category_*' columns at once!
    across(
      starts_with("category_"),
      # Based on matches within scope, "roll up" each column into the desired scalar.
      ~ if_else(any(code %in% .), first(expend), 0)
    )
  )

Výsledek

Vzhledem code_list takhle

# A list defined with regular syntax.
code_list <- list(
  category_1 = c("101", "102"),
  category_2 = c("201", "202", "203")
)

spolu s table takhle

table <- data.frame(
  id = c("1001", "1002", "1003", "1004", "1005"), 
  bin = c("0", "0", "1", "1", "0"),
  expend = c(111, 222, 333, 444, 555),
  code = c("101", "102", "201", "202", "102")
)

toto řešení by mělo přinést následující result:

# A tibble: 5 x 6
  id    bin   expend code  category_1 category_2
  <chr> <chr>  <dbl> <chr>      <dbl>      <dbl>
1 1001  0        111 101          111          0
2 1002  0        222 102          222          0
3 1003  1        333 201            0        333
4 1004  1        444 202            0        444
5 1005  0        555 102          555          0

Poznámka

Pokud váš code_list má prvky, jejichž názvy se odchylují od category_* úmluvou, budete muset nahradit každý výskyt starts_with("category_") s matches("some regex"), kde "some regex" je řetězec definující regulární výraz , který odpovídá přesně všechny názvy v code_list.

2021-12-02 14:35:26

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................