Построение таблицы из заданного набора данных с использованием R

#r

Вопрос:

У меня есть два набора данных символьного типа,

 a <- (ham, pizza, ham, ham, apple, Orange)

b <- (ham, guava, bread)
 

То, чего я пытаюсь достичь, — это таблица, как показано ниже:

         ham   guava  bread  pizza  apple  orange

a        3      0      0      1      1       1

b        1      1      1      0      0       0
 

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

Ответ №1:

 library(tidyverse)

a <- c("ham", "pizza", "ham", "ham", "apple", "Orange")
b <- c("ham", "guava", "bread")
c <- c("ham", "guava", "pizza")

# Hand code.
bind_rows(
   data.frame(food=a) %>% group_by(food) %>% summarise(n=n()) %>% pivot_wider(names_from = food, values_from = n)
  ,data.frame(food=b) %>% group_by(food) %>% summarise(n=n()) %>% pivot_wider(names_from = food, values_from = n)
) %>% mutate_all(replace_na, replace = 0L)

# Or we can make a function that can take a list of food character vectors
foods <- function(foods) {
  map(foods, function(x){
    data.frame(food=x) %>% group_by(food) %>% summarise(n=n()) %>% pivot_wider(names_from = food, values_from = n)
  }) %>% 
    reduce(bind_rows) %>%
    mutate_all(replace_na, replace = 0L)
}

foods(list(a,b,c))
 

Ответ №2:

Другой метод:

 library(dplyr)
library(tidyr)
library(tibble)
library(purrr)

a <- c("ham", "pizza", "ham", "ham", "apple", "Orange")
b <- c("ham", "guava", "bread")

list("a" = a, "b" = b) |> 
  map_dfr(.id = "data", ~ enframe(.x) |> 
            count(value) |> 
            pivot_wider(values_from = n, names_from = value)) |> 
  mutate(across(everything(), replace_na, 0))
#> # A tibble: 2 x 7
#>   data  apple   ham Orange pizza bread guava
#>   <chr> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>
#> 1 a         1     3      1     1     0     0
#> 2 b         0     1      0     0     1     1
 

Ответ №3:

Я думаю, что некоторые изменения и использование stack reshape2::dcast могут быть более простым решением:

 library(reshape2)
a <- c("ham", "pizza", "ham", "ham", "apple", "Orange")
b <- c("ham", "guava", "bread")

vars <- list(a, b)
names(vars) <- c("a", "b")

df <- dcast(stack(vars), ind ~ values, value.var = "ind", fun = length)
print(df)
 

И когда мы создадим для него функцию:

 vecs_to_df <- function(...){
  varnames <- unlist(lapply(substitute(list(...))[-1], deparse))
  vars <- list(...)
  names(vars) <- varnames
  df <- dcast(stack(vars), ind ~ values, value.var = "ind", fun = length)
  return(df)
}

a <- c("ham", "pizza", "ham", "ham", "apple", "Orange")
b <- c("ham", "guava", "bread")
x <- c("ham", "Orange", "pizza")
y <- c("guava", "apple", "bread")

df <- vecs_to_df(a, b, x, y)
print(df)
 

Ответ №4:

Более простой метод, использующий только фреймы данных в R

 df1=data.frame(table(a))
df2=data.frame(table(b))
 

Фреймы данных выглядят так

 > df1
       a Freq
1  apple    1
2    ham    3
3 Orange    1
4  pizza    1
> df2
      b Freq
1 bread    1
2 guava    1
3   ham    1
 

Затем мы можем объединить два кадра данных как

 result= merge(df1,df2,all = T, by.x = 'a',by.y = 'b')
names(result)=c("fruits","a","b")
 

Выход:

 > results
  fruits  a  b
1  apple  1 NA
2    ham  3  1
3 Orange  1 NA
4  pizza  1 NA
5  bread NA  1
6  guava NA  1
 

NA может быть заполнен следующим образом

 result[is.na(result)]=0
 

Ответ №5:

Вы можете stack векторы и использовать table .

 a <- c("ham", "pizza", "ham", "ham", "apple", "Orange")
b <- c("ham", "guava", "bread")

t(table(stack(mget(c("a","b")))))
#   values
#ind apple bread guava ham Orange pizza
#  a     1     0     0   3      1     1
#  b     0     1     1   1      0     0