Как я могу создать фрейм данных, когда у меня есть только значения для каждой ячейки (возможно, более одной строки на ячейку) и их столбец и индекс строки? - PullRequest
1 голос
/ 04 августа 2020

У меня есть фрейм данных, включающий значения для каждой ячейки (возможно, более одного значения), а также строку и индекс столбца.


df = data.frame(values = c(1,"Sven", 20,"Mueller","sept",2,30,"John","Mar","Hynes","Marc"), 
                colI = c(1,2,3,2,4,1,3,2,4,2,2), rowI = c(1,1,1,1,1,2,2,2,2,2,2))

И я хочу получить что-то похожее на следующий data.frame :

df_final= data.frame(Index = c(1,2), name = c("Sven, Mueller", "John, Hynes, Marc"), age = c(20,30), 
                     month = c("sept","Mar"))

Однако я не смог ничего сделать, и я также не нашел решения в Интернете. Я не могу найти решение для переноса значений в соответствующее место во фрейме данных, и я думаю, что еще более серьезная проблема заключается в том, что ячейки могут содержать разное количество значений.

Спасибо за вашу помощь .

Ответы [ 3 ]

1 голос
/ 04 августа 2020

Используя базу R, вы можете сначала aggregate ваши данные в одну строку, разделенную запятыми для каждой строки и индекса столбца, а затем использовать unstack.

temp <- aggregate(values~colI + rowI, df, toString)
unstack(temp, values~colI)

#  X1                X2 X3   X4
#1  1     Sven, Mueller 20 sept
#2  2 John, Hynes, Marc 30  Mar

данные

df <- structure(list(values = c("1", "Sven", "20", "Mueller", "sept", 
"2", "30", "John", "Mar", "Hynes", "Marc"), colI = c(1, 2, 3, 
2, 4, 1, 3, 2, 4, 2, 2), rowI = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 
2, 2)), class = "data.frame", row.names = c(NA, -11L))
0 голосов
/ 04 августа 2020

Другое решение

df %>% 
  pivot_wider(rowI, names_from = colI, values_from = values, values_fn = toString) %>% 
  select(-rowI) %>% 
  purrr::set_names(c("ID", "name", "age", "month"))
0 голосов
/ 04 августа 2020

Вы можете использовать dplyr, tidyr и stringr, все включено в tidyverse:

df %>%
# bring your data into a wider format
  pivot_wider(id_cols=rowI, names_from=colI, values_from=values, values_fn=list) %>% 
# remove the nested listing
  unnest(everything()) %>%
# rename the columns
  select(Index = rowI, name=`2`, age=`3`, month=`4`) %>%
# group all rows based on the index
  group_by(Index) %>%
# concatenate the name column
  mutate(name=str_c(name, collapse=", ")) %>%
# remove duplicates
  distinct()

возвращает

# A tibble: 2 x 4
# Groups:   Index [2]
  Index name              age   month
  <dbl> <chr>             <chr> <chr>
1     1 Sven, Mueller     20    sept 
2     2 John, Hynes, Marc 30    Mar 

Примечание: я изменил ваш ввод данных и добавил один 2 в столбец rowI (см. комментарий Маурица Эверса).

...