Как распределить один столбец на основе нескольких столбцов в R?

#r #multiple-columns #tidyr #spread

Вопрос:

Каждый уникальный год, участок, сектор и вид имеют два значения «Val» в наборе данных. Я хочу распределить значения в два столбца «Val1» и «Val2». Я пытался использовать обычную функцию распространения, но, похоже, она не подходит. Есть какие-нибудь предложения?

 Year Site Quadrant Species Val
2019   1     1        A    20
2019   1     1        A    30
2019   1     1        B    20
2019   1     1        B    25
2019   1     2        A    20
2019   1     2        A    10
2019   1     2        B    11
2019   1     2        B    22
 

Желаемый Результат

 Year Site Quadrant Species Val1 Val2
2019   1     1        A    20    30
2019   1     1        B    20    25
2019   1     2        A    20    10
2019   1     2        B    11    22
 

Ответ №1:

Вы можете group_by использовать столбцы, mutate чтобы создать новые заголовки столбцов, а затем spread (или pivot_wider ):

 library(dplyr)

mydata %>% 
  group_by(Year, Site, Quadrant, Species) %>% 
  mutate(Var = paste0("Val", row_number())) %>% 
  spread(Var, Val) %>%
  ungroup()
 

Результат:

 # A tibble: 4 x 6
   Year  Site Quadrant Species  Val1  Val2
  <int> <int>    <int> <chr>   <int> <int>
1  2019     1        1 A          20    30
2  2019     1        1 B          20    25
3  2019     1        2 A          20    10
4  2019     1        2 B          11    22
 

Данные:

 mydata <- read.table(text = "Year Site Quadrant Species Val
2019   1     1        A    20
2019   1     1        A    30
2019   1     1        B    20
2019   1     1        B    25
2019   1     2        A    20
2019   1     2        A    10
2019   1     2        B    11
2019   1     2        B    22", header = TRUE)
 

Ответ №2:

Вы можете сделать это следующим образом: с помощью lead

 library(tidyverse)
df %>% 
  mutate(id = row_number(),
         Val2 = lead(Val)) %>% 
  filter(id %% 2 == 1) %>% 
  select(-id, Val1  = Val)
 

Выход:

    Year  Site Quadrant Species  Val1  Val2
  <dbl> <dbl>    <dbl> <chr>   <dbl> <dbl>
1  2019     1        1 A          20    30
2  2019     1        1 B          20    25
3  2019     1        2 A          20    10
4  2019     1        2 B          11    22
 

данные:

 df <- tribble(
~Year, ~Site, ~Quadrant, ~Species, ~Val,
2019, 1, 1, "A", 20, 
  2019, 1, 1, "A", 30, 
  2019, 1, 1, "B", 20, 
  2019, 1, 1, "B", 25, 
  2019, 1, 2, "A", 20, 
  2019, 1, 2, "A", 10, 
  2019, 1, 2, "B", 11, 
  2019, 1, 2, "B", 22)
 

Ответ №3:

использование data.table::dcast и rowid :

 library(data.table)
dcast(dtt,
    Year   Site   Quadrant   Species ~ rowid(Year, Site, Quadrant, Species),
    value.var = 'Val')
#    Year Site Quadrant Species  1  2
# 1: 2019    1        1       A 20 30
# 2: 2019    1        1       B 20 25
# 3: 2019    1        2       A 20 10
# 4: 2019    1        2       B 11 22
 

Аналогичную операцию можно выполнить и другим способом, если вы предпочитаете:

 dtt %>%
    group_by(Year, Site, Quadrant, Species) %>%
    mutate(grp = row_number()) %>%
    pivot_wider(names_from = grp, values_from = Val, names_prefix = 'Val') %>%
    ungroup()

#  A tibble: 4 x 6
#    Year  Site Quadrant Species  Val1  Val2
#   <int> <int>    <int> <chr>   <int> <int>
# 1  2019     1        1 A          20    30
# 2  2019     1        1 B          20    25
# 3  2019     1        2 A          20    10
# 4  2019     1        2 B          11    22