R / dyplr: преобразование двух строк в два столбца - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть датафрейм в R, который выглядит так:

Word    Base    Number  Type
-       -       -       -
shoe    shoe    4834    singular
shoes   shoe    49955   plural
toy     toy     75465   singular
toys    toy     23556   plural
key     key     39485   singular
keys    key     6546    plural
jazz    jazz    58765   plural

Я бы хотел преобразовать его так, чтобы он выглядел так:

Word_Sg Word_Pl Base    Num_Singular    Num_Plural
--      --      --      --              --
shoe    shoes   shoe    4834            49955
toy     toys    toy     75465           23556
key     keys    key     39485           6546
NA      jazz    jazz    NA              58765

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

Я пробовал несколько вещей, используя dplyr::summarize, но пока безуспешно. Вот код, который я придумал до сих пор:

dataframe1 <- dataframe %>% 
      mutate(Num_Singular = case_when(Type == "singular" ~ Number)) %>%
      mutate(Num_Plural = case_when(Type == "plural" ~ Number)) %>%
      dplyr::select(Word, Base, Num_Singular, Num_Plural) %>%
      group_by(Base) %>%
      dplyr::summarize(Num_Singular = paste(na.omit(Num_Singular)),
                       Num_Plural = paste(na.omit(Num_Plural))

Однако, это дает мне эту ошибку:

Error in summarise_impl(.data, dots) : 
  Column `Num_Singular` must be length 1 (a summary value), not 2)

Я думаю, что проблема может заключаться в том, что есть строки, которые не обязательно имеют единственное и множественное число, а только либо (например, "джаз"). Большинство строк имеют оба, хотя.

Так как я могу сделать это в R или dplyr?

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

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

library(dplyr)
library(tidyr)

dat <- read.table(header = T, stringsAsFactors = F, text='
Word    Base    Number  Type
shoe    shoe    4834    singular
shoes   shoe    49955   plural
toy     toy     75465   singular
toys    toy     23556   plural
key     key     39485   singular
keys    key     6546    plural
jazz    jazz    58765   plural')

dat %>% 
  gather(variable, value, Word, Number) %>%
  unite(Type, variable, Type) %>%
  spread(Type, value, convert = T) %>% 
  as_tibble()

# # A tibble: 4 x 5
#   Base  Number_plural Number_singular Word_plural Word_singular
#   <chr>         <int>           <int> <chr>       <chr>        
# 1 jazz          58765              NA jazz        NA           
# 2 key            6546           39485 keys        key          
# 3 shoe          49955            4834 shoes       shoe         
# 4 toy           23556           75465 toys        toy  
0 голосов
/ 03 мая 2018

Вы можете присоединиться к plural и singular подмножествам ваших данных с помощью Base, затем удалить столбцы Type и изменить порядок остальных ...

full_join(filter(dat, Type == "plural"), 
          filter(dat, Type == "singular"),
          by = "Base", 
          suffix = c("_Pl", "_Sg")) %>% 
  select(Word_Sg, Word_Pl, Base, Number_Sg, Number_Pl)

#   Word_Sg Word_Pl Base Number_Sg Number_Pl
# 1    shoe   shoes shoe      4834     49955
# 2     toy    toys  toy     75465     23556
# 3     key    keys  key     39485      6546
# 4    <NA>    jazz jazz        NA     58765
0 голосов
/ 27 апреля 2018

Если вы впервые посмотрите на первые несколько столбцов ::

select(dat, Base, Word, Type)[1:2,]
#   Base  Word     Type
# 1 shoe  shoe singular
# 2 shoe shoes   plural

Отсюда, рассмотрим, как он просто распределяет его по столбцам в единственном / множественном числе, эффективно переходя от «высокого» к «широкому». (Было бы гораздо более очевидно, если бы в Type было более двух категорий.)

select(dat, Base, Word, Type) %>%
    spread(Type, Word) %>%
    rename(Word_Pl=plural, Word_Sg=singular)
#   Base Word_Pl Word_Sg
# 1 jazz    jazz    <NA>
# 2  key    keys     key
# 3 shoe   shoes    shoe
# 4  toy    toys     toy

Вы можете легко повторить это для Number. Оттуда, это просто вопрос слияния / объединения их на основе ключевого столбца, Base:

full_join(
  select(dat, Base, Word, Type) %>%
    spread(Type, Word) %>%
    rename(Word_Pl=plural, Word_Sg=singular),
  select(dat, Base, Number, Type) %>%
    spread(Type, Number) %>%
    rename(Num_Pl=plural, Num_Sg=singular),
  by = "Base"
)
#   Base Word_Pl Word_Sg Num_Pl Num_Sg
# 1 jazz    jazz    <NA>  58765     NA
# 2  key    keys     key   6546  39485
# 3 shoe   shoes    shoe  49955   4834
# 4  toy    toys     toy  23556  75465

Расходуемые данные:

library(dplyr)
library(tidyr)
dat <- read.table(text='Word    Base    Number  Type
shoe    shoe    4834    singular
shoes   shoe    49955   plural
toy     toy     75465   singular
toys    toy     23556   plural
key     key     39485   singular
keys    key     6546    plural
jazz    jazz    58765   plural', header=TRUE, stringsAsFactors=FALSE)
...