将向量列表转换为计数数据框
Convert List of Vectors into Data Frame of Counts
我有一个字符向量列表存储在这样的列表中:
basket1 <- c("Apple", "Orange", "Banana", "Apple", "Apple", "Grape")
basket2 <- c("Grape", "Grape", "Grape", "Grape")
basket3 <- c("Kiwi", "Apple", "Cantaloupe", "Banana")
basket4 <- c("Strawberry")
basket5 <- c("Grape", "Grape", "Grape")
FruitBasketList <- list(basket1, basket2, basket3, basket4, basket5)
我想将 FruitBasketList
变成一个数据框,其中每行中的每个水果的数量与它来自的篮子相匹配。我遇到的主要问题是每个向量中可能有数千个不同的 "fruits",并且其中很多会出现不止一次。
This is the desired data frame I would like as a result:
Basket Apple Orange Banana Grape Kiwi Cantaloupe Strawberry
basket1 3 1 1 1 0 0 0
basket2 0 0 0 4 0 0 0
basket3 1 0 1 0 1 1 0
basket4 0 0 0 0 0 0 1
basket5 0 0 0 3 0 0 0
显然,这不是我的真实数据,但我想我会简化数据的外观,以便任何人都能理解它。不,这不是家庭作业。无论如何,篮子里的水果数量可以是一千种不同的水果,每个水果向量的长度也不相同。也可以有数以万计的篮子(向量)。显然,一些水果可以在同一个向量(篮子)中重复多次。我一直在努力解决这个问题,但我确信它过于复杂且效率非常低下。到目前为止,我的解决方案包括组合所有向量中的所有向量,然后识别所有可能的唯一水果名称。结果很好。然后我正在努力的部分是从所有这些唯一的列名称中创建一个空数据框,然后为每个向量计算每个唯一的水果,然后将该值放在数据框中新行的正确列中该特定篮子中不存在的水果为零。
我用来计算单个向量的代码如下所示:
GetUniqueItemCount <- function(rle, value)
{
value <- rle$lengths[rle$values == value]
if (identical(value, integer(0)))
{
value <- 0
}
value
}
调用它的代码如下所示:
Apple <- GetUniqueItemCount(rle, "Apple")
正如您在我当前代码中看到的那样,我必须事先知道所有可能的水果,并对每个水果的数量进行硬编码,然后将其分配给数据框中事先已知的特定列。无论如何,我意识到我在这里走错了路,所以我很感激任何关于回到正轨以获取上面显示的所需数据框的建议。如果那是解决问题的最佳方法,请随时提供完全不同的方法,而不是试图弄清楚如何使我的工作正常。
使用dplyr
,我可能会做类似
的事情
library(dplyr)
m <- FruitBasketList %>% lapply(table) %>% lapply(as.list) %>%
lapply(data.frame) %>% rbind_all()
m
# Source: local data frame [5 x 7]
#
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
# 1 3 1 1 1 NA NA NA
# 2 NA NA 4 NA NA NA NA
# 3 1 1 NA NA 1 1 NA
# 4 NA NA NA NA NA NA 1
# 5 NA NA 3 NA NA NA NA
这会将缺失值保留为 NA。如果你想将它们设置为0,你可以这样做
m[is.na(m)]<-0
m
# Source: local data frame [5 x 7]
#
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
# 1 3 1 1 1 0 0 0
# 2 0 0 4 0 0 0 0
# 3 1 1 0 0 1 1 0
# 4 0 0 0 0 0 0 1
# 5 0 0 3 0 0 0 0
我建议 "qdapTools" 包中的 mtabulate
。
library(qdapTools)
mtabulate(FruitBasketList)
# Apple Banana Cantaloupe Grape Kiwi Orange Strawberry
# 1 3 1 0 1 0 1 0
# 2 0 0 0 4 0 0 0
# 3 1 1 1 0 1 0 0
# 4 0 0 0 0 0 0 1
# 5 0 0 0 3 0 0 0
package's author 甚至分享了您的头像。漂亮。
您可以在每一行上应用函数 table
,然后使用 gtools::smartbind
rbind 结果
您可以 melt
"list" 并使用 dcast
从 "long" 重塑为 "wide"
library(reshape2)
dcast(melt(setNames(FruitBasketList, ls(pattern='^basket'))), L1~value)
# L1 Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
#1 basket1 3 1 1 1 0 0 0
#2 basket2 0 0 4 0 0 0 0
#3 basket3 1 1 0 0 1 1 0
#4 basket4 0 0 0 0 0 0 1
#5 basket5 0 0 3 0 0 0 0
或使用 base R
函数 stack
和 table
df <- stack(setNames(FruitBasketList, ls(pattern='^basket')))
table(df[2:1])
# values
#ind Apple Banana Cantaloupe Grape Kiwi Orange Strawberry
# basket1 3 1 0 1 0 1 0
# basket2 0 0 0 4 0 0 0
# basket3 1 1 1 0 1 0 0
# basket4 0 0 0 0 0 0 1
# basket5 0 0 0 3 0 0 0
我有一个字符向量列表存储在这样的列表中:
basket1 <- c("Apple", "Orange", "Banana", "Apple", "Apple", "Grape")
basket2 <- c("Grape", "Grape", "Grape", "Grape")
basket3 <- c("Kiwi", "Apple", "Cantaloupe", "Banana")
basket4 <- c("Strawberry")
basket5 <- c("Grape", "Grape", "Grape")
FruitBasketList <- list(basket1, basket2, basket3, basket4, basket5)
我想将 FruitBasketList
变成一个数据框,其中每行中的每个水果的数量与它来自的篮子相匹配。我遇到的主要问题是每个向量中可能有数千个不同的 "fruits",并且其中很多会出现不止一次。
This is the desired data frame I would like as a result:
Basket Apple Orange Banana Grape Kiwi Cantaloupe Strawberry
basket1 3 1 1 1 0 0 0
basket2 0 0 0 4 0 0 0
basket3 1 0 1 0 1 1 0
basket4 0 0 0 0 0 0 1
basket5 0 0 0 3 0 0 0
显然,这不是我的真实数据,但我想我会简化数据的外观,以便任何人都能理解它。不,这不是家庭作业。无论如何,篮子里的水果数量可以是一千种不同的水果,每个水果向量的长度也不相同。也可以有数以万计的篮子(向量)。显然,一些水果可以在同一个向量(篮子)中重复多次。我一直在努力解决这个问题,但我确信它过于复杂且效率非常低下。到目前为止,我的解决方案包括组合所有向量中的所有向量,然后识别所有可能的唯一水果名称。结果很好。然后我正在努力的部分是从所有这些唯一的列名称中创建一个空数据框,然后为每个向量计算每个唯一的水果,然后将该值放在数据框中新行的正确列中该特定篮子中不存在的水果为零。
我用来计算单个向量的代码如下所示:
GetUniqueItemCount <- function(rle, value)
{
value <- rle$lengths[rle$values == value]
if (identical(value, integer(0)))
{
value <- 0
}
value
}
调用它的代码如下所示:
Apple <- GetUniqueItemCount(rle, "Apple")
正如您在我当前代码中看到的那样,我必须事先知道所有可能的水果,并对每个水果的数量进行硬编码,然后将其分配给数据框中事先已知的特定列。无论如何,我意识到我在这里走错了路,所以我很感激任何关于回到正轨以获取上面显示的所需数据框的建议。如果那是解决问题的最佳方法,请随时提供完全不同的方法,而不是试图弄清楚如何使我的工作正常。
使用dplyr
,我可能会做类似
library(dplyr)
m <- FruitBasketList %>% lapply(table) %>% lapply(as.list) %>%
lapply(data.frame) %>% rbind_all()
m
# Source: local data frame [5 x 7]
#
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
# 1 3 1 1 1 NA NA NA
# 2 NA NA 4 NA NA NA NA
# 3 1 1 NA NA 1 1 NA
# 4 NA NA NA NA NA NA 1
# 5 NA NA 3 NA NA NA NA
这会将缺失值保留为 NA。如果你想将它们设置为0,你可以这样做
m[is.na(m)]<-0
m
# Source: local data frame [5 x 7]
#
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
# 1 3 1 1 1 0 0 0
# 2 0 0 4 0 0 0 0
# 3 1 1 0 0 1 1 0
# 4 0 0 0 0 0 0 1
# 5 0 0 3 0 0 0 0
我建议 "qdapTools" 包中的 mtabulate
。
library(qdapTools)
mtabulate(FruitBasketList)
# Apple Banana Cantaloupe Grape Kiwi Orange Strawberry
# 1 3 1 0 1 0 1 0
# 2 0 0 0 4 0 0 0
# 3 1 1 1 0 1 0 0
# 4 0 0 0 0 0 0 1
# 5 0 0 0 3 0 0 0
package's author 甚至分享了您的头像。漂亮。
您可以在每一行上应用函数 table
,然后使用 gtools::smartbind
您可以 melt
"list" 并使用 dcast
library(reshape2)
dcast(melt(setNames(FruitBasketList, ls(pattern='^basket'))), L1~value)
# L1 Apple Banana Grape Orange Cantaloupe Kiwi Strawberry
#1 basket1 3 1 1 1 0 0 0
#2 basket2 0 0 4 0 0 0 0
#3 basket3 1 1 0 0 1 1 0
#4 basket4 0 0 0 0 0 0 1
#5 basket5 0 0 3 0 0 0 0
或使用 base R
函数 stack
和 table
df <- stack(setNames(FruitBasketList, ls(pattern='^basket')))
table(df[2:1])
# values
#ind Apple Banana Cantaloupe Grape Kiwi Orange Strawberry
# basket1 3 1 0 1 0 1 0
# basket2 0 0 0 4 0 0 0
# basket3 1 1 1 0 1 0 0
# basket4 0 0 0 0 0 0 1
# basket5 0 0 0 3 0 0 0