r语言 - 矩阵乘法器错误 - 将最大值切换为总和



>我有两个数据框,一个是在一个位置发现的动物信息(df1(,另一个是关于动物特征的信息(df2(

我正在尝试使用矩阵乘数 (%*%( 并应用"总和"和"最大值"等函数并获取每个位置的信息。

例如:

df1:
Location No. Dog Cat Cow Sheep
1            0   2   2   1
2            0   1   0   1
3            0   0   0   1
4            0   0   2   1
df2:
Name of Animal  BodySize   FavoriteScore
Dog             40         10
Cat             20         08
Cow             100        05
Sheep           60         07

我的目标是获取诸如 1. 每个地点有多少种动物? 2. 每个地点发现的最大的动物是什么?(其中比较所有动物,并选择最大的体型并交付( 3. 每个地点哪只动物的最爱分数最高?(其中比较所有动物,并选择最大的收藏夹分数并交付(

为了获得这个,我使用以下代码:

Typemaker <- function (n) {
o<-sum(n>0)
return(o)
} 
apply(df1[,1:4] ,1, Typemaker)
df1$sumtype <- apply(df1[,2:5] ,1, Typemaker)
and 
Favoritemaker <- function (n) {
o<- max(n %*% df2$FavoriteScore)
return(o)
} 
apply(df1[,1:4] ,1, Favoritemaker)
df1$Favorite <-  apply(df1[,2:5] ,1, Favoritemaker)
or 
Bodysizemaker <- function (n) {
o<- max(n %*% df2$BodySize)
return(o)
} 
apply(df1[,1:4] ,1, Bodysizemaker).
df1$Bodysize <- apply(df1[,2:5] ,1, Bodysizemaker).

所以我的答案将显示为:

Location No. Dog Cat Cow Sheep Type Favorite Bodysize
1            0   2   2   1     3    08       100
2            0   1   0   1     2    08       20
3            0   0   0   1     1    07       60
4            0   0   2   1     2    07       100

但是,正文大小和收藏夹分数作为行的总和而不是最大值提供。

我不确定到底是什么问题。

我将不胜感激任何帮助。

我注意到的一件事是,当您使用apply调用每个函数时,您使用的是前四列,df1[,1:4]包括位置编号并排除 Sheep 数据。 您应该将其更改为df1[,2:5]

我从来没有使用过矩阵乘数,%*%,所以我不能说出使用它来解决这个问题的正确方法,或者即使它是一种正确的方法。 但是由于您有数据框,因此以下是使用dplyr获得所需结果的一种非常笨拙的方法:

library(tidyverse)
df1 <- data.frame(`Location No.` = c(1:4),
Dog = rep(0,4),
Cat = c(2,1,0,0),
Cow = c(2,0,0,2),
Sheep = rep(1,4))
df2 <- data.frame(`Name of Animal` = c("Dog", "Cat", "Cow", "Sheep"),
BodySize = c(40, 20, 100, 60),
FavoriteScore = c(10, 8, 5, 7))
dfout <- df1 %>% 
mutate(DogSize = ifelse(Dog > 0, df2$BodySize[df2$Name.of.Animal == "Dog"], 0),
CatSize = ifelse(Cat > 0, df2$BodySize[df2$Name.of.Animal == "Cat"], 0),
CowSize = ifelse(Cow > 0, df2$BodySize[df2$Name.of.Animal == "Cow"], 0),
SheepSize = ifelse(Sheep > 0, df2$BodySize[df2$Name.of.Animal == "Sheep"], 0)) %>%
mutate(DogScore = ifelse(Dog > 0, df2$FavoriteScore[df2$Name.of.Animal == "Dog"], 0),
CatScore = ifelse(Cat > 0, df2$FavoriteScore[df2$Name.of.Animal == "Cat"], 0),
CowScore = ifelse(Cow > 0, df2$FavoriteScore[df2$Name.of.Animal == "Cow"], 0),
SheepScore = ifelse(Sheep > 0, df2$FavoriteScore[df2$Name.of.Animal == "Sheep"], 0)) %>% 
rowwise() %>% 
mutate(Bodysize = max(DogSize, CatSize, CowSize, SheepSize),
Favorite = max(DogScore, CatScore, CowScore, SheepScore)) %>% 
select(Location.No., Dog, Cat, Cow, Sheep, Favorite, Bodysize)

肯定有更有效的方法可以做到这一点,特别是如果你的数据集更大,但这会让你进入你在问题末尾显示的表格:

Location.No. Dog Cat Cow Sheep Favorite Bodysize
1            0   2   2   1     8        100
2            0   1   0   1     8        60
3            0   0   0   1     7        60
4            0   0   2   1     7        100

更新

好的,所以我对自己的学习非常好奇,所以下面是一个更新的代码,它使用收集和传播来使该过程对于具有更多列的数据集更加通用。 这应该适用于更多列,前提是结构类似于您显示的示例数据。

df_long <- gather(df1, animal, count, Dog:Sheep, factor_key = TRUE)

这将采用宽格式的第一个数据框,并将其转换为长格式以便于操作。 只需将Dog:Sheep替换为动物列的范围即可。

df_modified <- df_long %>% 
rowwise() %>% 
# assign favorite score and body size by animal
mutate(Favorite = df2$FavoriteScore[df2$Name.of.Animal == animal],
Bodysize = df2$BodySize[df2$Name.of.Animal == animal]) %>% 
# eliminate score and body size for animals without a count
mutate(Favorite = case_when(count == 0 ~ 0,
TRUE ~ Favorite)) %>% 
mutate(Bodysize = case_when(count == 0 ~ 0,
TRUE ~ Bodysize)) %>% 
# use group_by and max() to get the max value for each location
group_by(Location.No.) %>% 
mutate(Favorite = max(Favorite),
Bodysize = max(Bodysize))

# use spread to put the data frame back into the wide format
df_wide <- spread(df_modified, animal, count)
# use as.data.frame to get from tibble to dataframe
df_out <- as.data.frame(df_wide)

新输出如下所示:

Location.No. Favorite Bodysize Dog Cat Cow Sheep
1            8        100      0   2   2   1
2            8        60       0   1   0   1
3            7        60       0   0   0   1
4            7        100      0   0   2   1

最新更新