如何使用 R 在数据矩阵中添加具有新列的相同字符串的总数
How to add total number of same string with new column in data matrix with R
假设我有一个矩阵,5 x 5,带有水果名称(5 class 个水果)。我想在这个现有矩阵中添加 5 个新列,每行中包含单个水果的总数,最后添加一行来显示每种相同水果的总和。数据矩阵是这样的,
[,1] [,2] [,3] [,4] [,5]
[1,]mango banana mango
[2,]apple kiwi banana
[3,] mango
[4,]mango apple
[5,] orange
我想得到这样的输出(数据框),
[,1] [,2] [,3] [,4] [,5] [apple] [banana] [kiwi] [mango] [orange]
[1,]mango banana mango 0 1 0 2 0
[2,]apple kiwi banana 1 1 1 0 0
[3,] mango 0 0 0 1 0
[4,]mango apple 1 0 0 1 0
[5,] orange 0 0 0 0 1
[6,] 2 2 1 4 1
我试过grep
,它正在将整个矩阵分解成一个列向量。我实际上不知道如何使用 R 对整个数据矩阵执行此操作。这是代码,
fruits <- matrix(c("mango", "", "banana", "", "mango", "apple", "kiwi", "", "banana", "","", "", "mango", "", "", "mango", "", "apple", "", "", "", "", "", "orange", ""), nrow = 5, ncol = 5, byrow = TRUE)
fruits$apple <- length(grep("apple", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$banana <- length(grep("banana", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$kiwi <- length(grep("kiwi", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$mango <- length(grep("mango", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$orange <- length(grep("orange", fruits[1:nrow(fruits), 1:ncol(fruits)]))
请帮忙。
无法使用矩阵创建您指定的输出,因为矩阵包含单一类型的值。因此,计数将转换为字符,这是一种解决方案,但可能不是您想要的。我建议您使用数据框来存储您的结果。
我提出以下四步解决方案。
创建矩阵中所有水果名称的向量。我使用额外的步骤从该向量中删除空字符串。
all_fruits <- unique(as.vector(fruits))
all_fruits <- all_fruits[nchar(all_fruits) > 0]
创建一个列表,其中包含 all_fruits
中每个水果每行的计数。
fruit_count <- lapply(all_fruits, function(fruit)
rowSums(matrix(grepl(fruit, fruits), nrow = nrow(fruits))))
names(fruit_count) <- all_fruits
这部分有点棘手,所以我补充几句。您需要使用 grepl
才能 return 一个逻辑向量。不幸的是,fruits
的维数参数丢失了,并且一个简单的向量被 returned 必须转换回矩阵。 rowSums
然后用于总结在每一行中找到搜索词(即水果名称)的次数。这是有效的,因为这样做时 TRUE
被转换为 1 而 FALSE
被转换为 0。
将 fruits
转换为数据框并添加带有空字符的附加行。将 fruit_count
转换为数据框并添加列总和。
fruits_df <- rbind(as.data.frame(fruits), "")
fruit_count_df <- as.data.frame(fruit_count)
fruit_count_df[nrow(fruits) + 1, ] <- colSums(fruit_count_df)
将两个数据框放在一起。
out <- data.frame(fruits_df, fruit_count_df)
out
## X1 X2 X3 X4 X5 mango apple kiwi banana orange
## 1 mango banana mango 2 0 0 1 0
## 2 apple kiwi banana 0 1 1 1 0
## 3 mango 1 0 0 0 0
## 4 mango apple 1 1 0 0 0
## 5 orange 0 0 0 0 1
## 6 4 2 1 2 0
我们也可以用计数来融化和铸造数据框。然后加上一行求和:
library(reshape2)
library(tidyr)
#melt fruits matrix
g <- gather(as.data.frame(t(fruits)))
#cast data wide and bind to original matrix
d <- cbind(fruits, dcast(g, key~value)[-(1:2)])
#add row of sums
rbind(d,c(rep("", 5),colSums(d[-(1:5)])))
# 1 2 3 4 5 apple banana kiwi mango orange
# 1 mango banana mango 0 1 0 2 0
# 2 apple kiwi banana 1 1 1 0 0
# 3 mango 0 0 0 1 0
# 4 mango apple 1 0 0 1 0
# 5 orange 0 0 0 0 1
# 6 2 2 1 4 1
假设我有一个矩阵,5 x 5,带有水果名称(5 class 个水果)。我想在这个现有矩阵中添加 5 个新列,每行中包含单个水果的总数,最后添加一行来显示每种相同水果的总和。数据矩阵是这样的,
[,1] [,2] [,3] [,4] [,5]
[1,]mango banana mango
[2,]apple kiwi banana
[3,] mango
[4,]mango apple
[5,] orange
我想得到这样的输出(数据框),
[,1] [,2] [,3] [,4] [,5] [apple] [banana] [kiwi] [mango] [orange]
[1,]mango banana mango 0 1 0 2 0
[2,]apple kiwi banana 1 1 1 0 0
[3,] mango 0 0 0 1 0
[4,]mango apple 1 0 0 1 0
[5,] orange 0 0 0 0 1
[6,] 2 2 1 4 1
我试过grep
,它正在将整个矩阵分解成一个列向量。我实际上不知道如何使用 R 对整个数据矩阵执行此操作。这是代码,
fruits <- matrix(c("mango", "", "banana", "", "mango", "apple", "kiwi", "", "banana", "","", "", "mango", "", "", "mango", "", "apple", "", "", "", "", "", "orange", ""), nrow = 5, ncol = 5, byrow = TRUE)
fruits$apple <- length(grep("apple", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$banana <- length(grep("banana", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$kiwi <- length(grep("kiwi", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$mango <- length(grep("mango", fruits[1:nrow(fruits), 1:ncol(fruits)]))
fruits$orange <- length(grep("orange", fruits[1:nrow(fruits), 1:ncol(fruits)]))
请帮忙。
无法使用矩阵创建您指定的输出,因为矩阵包含单一类型的值。因此,计数将转换为字符,这是一种解决方案,但可能不是您想要的。我建议您使用数据框来存储您的结果。
我提出以下四步解决方案。
创建矩阵中所有水果名称的向量。我使用额外的步骤从该向量中删除空字符串。
all_fruits <- unique(as.vector(fruits)) all_fruits <- all_fruits[nchar(all_fruits) > 0]
创建一个列表,其中包含
all_fruits
中每个水果每行的计数。fruit_count <- lapply(all_fruits, function(fruit) rowSums(matrix(grepl(fruit, fruits), nrow = nrow(fruits)))) names(fruit_count) <- all_fruits
这部分有点棘手,所以我补充几句。您需要使用
grepl
才能 return 一个逻辑向量。不幸的是,fruits
的维数参数丢失了,并且一个简单的向量被 returned 必须转换回矩阵。rowSums
然后用于总结在每一行中找到搜索词(即水果名称)的次数。这是有效的,因为这样做时TRUE
被转换为 1 而FALSE
被转换为 0。将
fruits
转换为数据框并添加带有空字符的附加行。将fruit_count
转换为数据框并添加列总和。fruits_df <- rbind(as.data.frame(fruits), "") fruit_count_df <- as.data.frame(fruit_count) fruit_count_df[nrow(fruits) + 1, ] <- colSums(fruit_count_df)
将两个数据框放在一起。
out <- data.frame(fruits_df, fruit_count_df) out ## X1 X2 X3 X4 X5 mango apple kiwi banana orange ## 1 mango banana mango 2 0 0 1 0 ## 2 apple kiwi banana 0 1 1 1 0 ## 3 mango 1 0 0 0 0 ## 4 mango apple 1 1 0 0 0 ## 5 orange 0 0 0 0 1 ## 6 4 2 1 2 0
我们也可以用计数来融化和铸造数据框。然后加上一行求和:
library(reshape2)
library(tidyr)
#melt fruits matrix
g <- gather(as.data.frame(t(fruits)))
#cast data wide and bind to original matrix
d <- cbind(fruits, dcast(g, key~value)[-(1:2)])
#add row of sums
rbind(d,c(rep("", 5),colSums(d[-(1:5)])))
# 1 2 3 4 5 apple banana kiwi mango orange
# 1 mango banana mango 0 1 0 2 0
# 2 apple kiwi banana 1 1 1 0 0
# 3 mango 0 0 0 1 0
# 4 mango apple 1 0 0 1 0
# 5 orange 0 0 0 0 1
# 6 2 2 1 4 1