R: преобразование вертикальных данных в горизонтальный формат с условными - PullRequest
3 голосов
/ 17 января 2020

Я пытаюсь преобразовать фрейм данных с вертикальным форматом в горизонтальный формат. Я знаком с функцией dcast. Тем не менее, я хотел бы обновить левую часть уравнения dcast условным полем, которое станет строкой. Вот конкретный пример c:

df = data.frame(ID=c(3,3,3,3,3,3,3,3,4,4,4,4),
                Field=rep(c("Color","Height","Weight","Condition"),3),
                Values=c("blue",72,140,"ON","blue",72,180,"OFF","green",80,162,"OFF"))

enter image description here

Вы заметите, что если мы агрегируем только на основе ID, быть множественными совпадениями, потому что существует несколько значений, когда поле равно "Condition" (то есть ID 3 имеет как ON, так и OFF условие для Condition). Таким образом, я хотел бы сначала начать с извлечения этого столбца, а затем применить dcast, чтобы получить такой кадр данных:

desiredDF = data.frame(ID=c(3,3,4),
                       Condition=c("ON","OFF","OFF"),
                       Color=c("blue","blue","green"),
                       Height=c(72,72,80),
                       Weight=c(140,180,162))

enter image description here

Есть идеи?

Ответы [ 4 ]

2 голосов
/ 17 января 2020

Вы можете использовать chop для вложения Values, соответствующего каждому (ID, Field) кортежу, спреду Field с и Values и unnest() после:

library(tidyverse)

df %>%
  chop(Values) %>%
  spread(Field, Values) %>%
  unnest(-1)

# # A tibble: 3 x 5
#      ID Color Condition Height Weight
#   <dbl> <fct> <fct>     <fct>  <fct> 
# 1     3 blue  ON        72     140   
# 2     3 blue  OFF       72     180   
# 3     4 green OFF       80     162   
2 голосов
/ 17 января 2020

Вот базовое решение R с использованием unstack() + cbind()

dfout <- cbind(t(unique(t(unstack(df, ID ~ Field)))), unstack(df, Values ~ Field))

таким, что

> dfout
  Color Color Condition Height Weight
1     3  blue        ON     72    140
2     3  blue       OFF     72    180
3     4 green       OFF     80    162
0 голосов
/ 17 января 2020

Если вы хотите использовать dcast, вы можете сделать следующее (ниже). Это позволило бы дублировать значения для каждого ID. При добавлении key будет использоваться Color для определения новой строки данных в желаемом окончательном наборе данных, основанной на том, как данные в настоящее время организованы.

library(data.table)

dcast(setDT(df), ID + ave(key <- Field == "Color", ID, FUN = cumsum) ~ Field, value.var = "Values")

Вывод

   ID key Color Condition Height Weight
1:  3   1  blue        ON     72    140
2:  3   2  blue       OFF     72    180
3:  4   1 green       OFF     80    162
0 голосов
/ 17 января 2020

Здесь есть два пути: «старая школа» и «новая школа»


library(tidyverse)
df %>%
  mutate(ID2 = cumsum(Field == "Color") ) %>%
  spread(Field, Values) %>%
  select(-ID2)
#>   ID Color Condition Height Weight
#> 1  3  blue        ON     72    140
#> 2  3  blue       OFF     72    180
#> 3  4 green       OFF     80    162

df %>%
  mutate(ID2 = cumsum(Field == "Color") ) %>%
  pivot_wider(values_from  = "Values", names_from = "Field") %>%
  select(-ID2)
#> # A tibble: 3 x 5
#>      ID Color Height Weight Condition
#>   <dbl> <fct> <fct>  <fct>  <fct>    
#> 1     3 blue  72     140    ON       
#> 2     3 blue  72     180    OFF      
#> 3     4 green 80     162    OFF

Нам нужно создать ID2 здесь, потому что ваши категории не могут быть поняты только по данным, нам нужны человеческие знания о том, что существует повторяемая последовательность здесь. ID2 проясняет.

...