使用 Tidyverse 重写当 Total 在一行中时计算百分比列的 For 循环

Rewrite a For Loop that Calculates Percentage Column when Total is in a Row Using Tidyverse

library(tidyverse)

我想使用 dplyr、tidyr 和 purrr 用 Tidyverse 语法重写下面的 for 循环代码。

for (i in seq_along(Data3)) {
Data3[[i]]$Count <- as.numeric(Data3[[i]]$Count)
n <- nrow(Data3[[i]])
Data3[[i]]$perc <- Data3[[i]]$Count / Data3[[i]]$Count[n]
} 

示例数据如下:

Loc<-c("Montreal","Toronto","Vancouver","Quebec","Ottawa","Hamilton","Total")
Count<-c("2344","2322","122","45","4544","44","9421")

Data<-data_frame(Loc,Count)
Data2<-data_frame(Loc,Count)
Data3<-list(Data,Data2)

这就是我要实现的目标:

每个数据框在 "Loc" 列中有 "Total",相应的总计为 "Count" 列。我想通过将 "Count" 列中的每个值除以总数来计算每个数据帧的百分比,总数是 "Count" 列中的最后一个数字。

我希望将百分比添加为每个数据框的新列。 对于这个例子,总数是列中的最后一个数字,但实际上,它可能在列中的任何位置混合,可以通过 "Loc" 列中相应的 "Total" 值找到。

我一直在尝试使用 purrr::map,但我不确定如何计算百分比。

Data3%>%map(~mutate(.x,paste0(round(100*  (MISSING PERCENTAGE),2),"%"))  

如果您想保留 "Total" 行,这将执行您的任务。但是,在单个列中混合不同类型的值对于您的数据来说是一种非常不整洁的形式。风险自负。

Data %>% 
  mutate(Count_type = ifelse(Loc == "Total", "Total", "Component") %>% 
  group_by(Count_type) %>%
  mutate(Count_pct = Count/sum(Count))

更好的解决方案是简单地删除 "Total" 行,因为它们可以很容易地计算为额外的列。

Data %>% 
  filter(Loc != "Total") %>%
  mutate(Count_pct = Count/sum(Count))

Data3 而言,您将数据帧存储在列表中是否有原因?你是对的 purrr 可以解决这个问题,但还有更简单的方法:

Data3 <- bind_rows("Data" = Data, "Data2" = Data2, .id = "Source") %>% group_by(Source)

然后只需将 Data3 替换为上述任一管道的开始。

如果您使用列表是因为您的数据出于某种原因以列表的形式出现,那么您的 map 代码接近正确。您应该能够弄清楚如何使用这些片段来处理数据帧列表。

我将使用基础 R:

首先确保您的数据具有 Loc 作为字符而不是因子:

 Loc<-c("Montreal","Toronto","Vancouver","Quebec","Ottawa","Hamilton","Total")
 Count<-c(2344,2322,122,45,4544,44,9421)

 Data<-data.frame(Loc,Count,stringsAsFactors = F)

 Data3<-list(Data,Data)

 lapply(Data3,function(x) {x[,"Percentage"]=100*x[,2]/x[x[,1]=="Total",2];x})


 [[1]]
         Loc Count  Percentage
 1  Montreal  2344  24.8805859
 2   Toronto  2322  24.6470651
 3 Vancouver   122   1.2949793
 4    Quebec    45   0.4776563
 5    Ottawa  4544  48.2326717
 6  Hamilton    44   0.4670417
 7     Total  9421 100.0000000

 [[2]]
         Loc Count  Percentage
 1  Montreal  2344  24.8805859
 2   Toronto  2322  24.6470651
 3 Vancouver   122   1.2949793
 4    Quebec    45   0.4776563
 5    Ottawa  4544  48.2326717
 6  Hamilton    44   0.4670417
 7     Total  9421 100.0000000

purr 中的 map 和 Base R 中的 Map 之间没有太大区别。如果你的目标是确实使用 map。然后我可以给出如下提示,它会给出与上面相同的解决方案,逻辑几乎相似:

Data3%>%map(~mutate(.x,'%'=100*Count/Count[Loc=="Total"]))

我用了 % 符号..我本可以写百分比...

希望这会有所帮助