Как разделить большой фрейм данных на основе других значений фрейма?

2

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

df1:

name   S1   S2   S3   S4   S5   S6   S7
 ABC   56   67   90   78   45   34   23
 HJG   12   32   13   99   55   89   25
 KLI   88   36   95   21   66   74   45
 JHU   32   55   65   77   88   16   40
 DFR   65   90   87   11   98   67   37

df2:

name   S1   S3  S5   S2    S4   S7    S6
 DFR    0   -1   -1   1    -2    1    -1
 JHU    1   -2    2   1     2    0     1
 HJG   -2    0    1   1    -2   -2    -1
 ABC   -1    2   -2   1     0    1     0
 KLI    2    1    0  -1     1    0    -2

Я хочу разбить df1 на две группы на основе значений в df2.

  • Группа 1 из df1 должна основываться на значениях (1,2) в df2
  • Группа 2 из df1 должна основываться на значениях (-1, - 2,0) в df2

например:

Group1:                             Group2:

 name  S1   S3   S4                  name  S2   S5   S6  S7
 KLI   88   95   21                  KLI   36   66   74  45

Точно так же мне нужно повторить все остальные имена. Может ли кто-нибудь сказать мне, как это сделать в R или Python?

Теги:
dataframe
split

1 ответ

2
Лучший ответ

Приведенный ниже код предоставит вам кадр данных в длинной форме с помощью маркеров группы. Код работает следующим образом:

  1. Преобразование как данные, кадры из "широкого" в "длинный" формат ( с помощью gather), а затем присоединиться к ним (используя left_join).
  2. Создайте столбец group на основе значений в df2 которые вы указали.
  3. Удалить ненужные столбцы
  4. Сортировать

Все эти шаги соединены вместе с помощью оператора трубы dplyr (%>%).

library(tidyverse)

df.new = df1 %>% gather(key, value, -name) %>%
  left_join(df2 %>% gather(key, value, -name), by=c("name","key"), suffix=c("1","2")) %>%
  mutate(group = ifelse(value2 >=1, "Group 1", "Group 2")) %>%
  select(name, key, value=value1, group) %>%
  arrange(group, name, key)
   name key value   group
1   ABC  S2    67 Group 1
2   ABC  S3    90 Group 1
3   ABC  S7    23 Group 1
...
13  KLI  S1    88 Group 1
14  KLI  S3    95 Group 1
15  KLI  S4    21 Group 1
...
32  KLI  S2    36 Group 2
33  KLI  S5    66 Group 2
34  KLI  S6    74 Group 2
35  KLI  S7    45 Group 2

Если вы действительно хотите, чтобы каждая группа была в отдельном кадре данных, вы можете split по group в конце цепочки, что даст вам список, содержащий два кадра данных: по одному для каждого уровня group:

df.list = df1 %>% gather(key, value, -name) %>%
  left_join(df2 %>% gather(key, value, -name), by=c("name","key"), suffix=c("1","2")) %>%
  mutate(group = ifelse(value2 >=1, "Group 1", "Group 2")) %>%
  select(name, key, value=value1, group) %>%
  arrange(group, name, key) %>%
  split(.$group)

Чтобы сохранить вывод в файле csv или xlsx:

Для первого примера, где у нас есть один кадр данных:

write.csv(df.new, "file_name.csv", row.names=FALSE)

library(xlsx)
write.xlsx(df.new, "file_name.xlsx", row.names=FALSE)

Во втором примере, когда у нас есть список, содержащий более одного фрейма данных, мы будем писать каждый кадр данных для разделения файла csv. Для файла Excel мы будем писать оба кадра данных на разные листы в одной книге Excel:

# Write to two different csv files
map(names(df.list), function(x) write.csv(df.list[[x]], paste0(x,".csv"), row.names=FALSE))

# Write to two different sheets in the same Excel file
library(xlsx)
map(names(df.list), function(x) write.xlsx(df.list[[x]], "my_file.xlsx", sheet=x, append=TRUE, row.names=FALSE))
  • 0
    Я получил Group1 и Group2. Но как сохранить их в CSV или текстовом файле? или во фрейм данных?
  • 1
    Первый пример уже является фреймом данных. Второй пример - список с двумя фреймами данных в качестве элементов. Вам просто нужно назначить вывод для объекта, и он будет доступен в вашем рабочем пространстве. Я изменил свой ответ, чтобы сделать это явно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню