#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