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

R 矩阵乘法器错误-将最大值切换为总和,r,matrix,sum,max,matrix-multiplication,R,Matrix,Sum,Max,Matrix Multiplication,我有两个数据框,一个是关于在一个位置发现的动物的信息(df1),另一个是关于动物特征的信息(df2) 我正在尝试使用矩阵乘法器(%*),并应用“sum”和“max”等函数,以获取每个位置的信息 例如: df1: Location No. Dog Cat Cow Sheep 1 0 2 2 1 2 0 1 0 1 3 0 0 0 1 4 0

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

我正在尝试使用矩阵乘法器(%*),并应用“sum”和“max”等函数,以获取每个位置的信息

例如:

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.哪种动物在每个位置的最受欢迎分数最高?(其中,对所有动物进行比较,并选择最大的favoritescore,然后进行传递)

为了获得此信息,我使用以下代码:

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).
但是,车身尺寸和偏好分数是作为行的总数而不是最大值提供的

我不确定到底是什么问题


如果有任何帮助,我将不胜感激。

我注意到的一件事是,当您使用
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)
更新

好吧,我对我自己的学习非常好奇,下面是一段更新的代码,它使用了聚集和扩散,使这个过程对于具有更多列的数据集来说更加通用。如果结构与您显示的示例数据相似,则可以使用更多列

df_long <- gather(df1, animal, count, Dog:Sheep, factor_key = TRUE)
新输出如下所示:

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

您认为
%*%
操作员应该做什么?请描述您想做什么。您的问题目前讨论的是您的方法,但没有明确描述您打算让其成为XY问题的内容。目前还不清楚您打算用
%*%
做什么,以及这应该如何依赖
max
@NelsonGon:现在阅读问题更好了吗?@Roland:现在阅读问题更好了吗?@Roland:为什么这么说?谢谢:)但我的原始数据由两个数据帧组成,一个有104行,另一个有50种动物,所以我有点害怕这样做,因为我可能最终会出错。是的!非常感谢你指出错误,我会改正的it@KeerthiKrutha我更新了答案,试图在更大的数据集上更灵活。希望这对你有用。
df_long <- gather(df1, animal, count, Dog:Sheep, factor_key = TRUE)
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