[英]Checking sums with condition in R
我需要檢查一些 dataframe 中的總和。 但它的元素不能總結,因為其中一些包含其他元素。 在這個例子中,051040 是 051043 的一部分。雖然大多數元素以“0”結尾,但最后一位為 3 的元素總是大於或等於最后一位為 0 的對應元素。換句話說,我需要找到所有以“3”結尾的元素並跳過那些帶有“0”的對應物。 在此示例中,必須跳過 051040 和 051050,因為存在 051043 和 051053。 注意元素“05000”是一個控制和,顯然它也必須被跳過。 所以我需要找出差異:05000 - SUM ("051010", "051043", "051053", "052020", "052100", "052220", "052310") = 0 類似的東西。 這是一個人工的例子(實際的dataframe真的很大)。
Area <- c("050000", "051010", "051040", "051043", "051050", "051053", "052020", "052100", "052220", "052310")
Total <- c(100, 28, 16, 22, 10, 10, 10, 10, 10, 10)
sodf <- data.frame(Area, Total)
首先十分感謝!
您可以使用子字符串。
sodf[with(sodf, ave(substring(Area, 6) == 3, substr(Area, 1, 5), FUN=\(x) {
if (any(x)) x else TRUE
})), ] |>
(\(x) x[1, 2] - sum(x[-1, 2]))()
# [1] 0
在多個區域的應用程序中,我稍微sodf
lapply
進行演示(但不完全確定您的區號看起來如何,但前兩位數字似乎相關)。
lapply(split(sodf, substr(sodf$Area, 1, 2)), \(x) {
x <- x[ave(substring(Area, 6) == 3, substr(Area, 1, 5), FUN=\(x) {
if (any(x)) x else TRUE
}), ]
x[1, 2] - sum(x[-1, 2])
})
# $`05`
# [1] 0
#
# $`06`
# [1] 111
數據:
sodf <- structure(list(Area = c("050000", "051010", "051040", "051043",
"051050", "051053", "052020", "052100", "052220", "052310", "060000",
"061010", "061040", "061043", "061050", "061053", "062020", "062100",
"062220", "062310"), Total = c(100, 28, 16, 22, 10, 10, 10, 10,
10, 10, 211, 28, 16, 22, 10, 10, 10, 10, 10, 10)), row.names = c(NA,
-20L), class = "data.frame")
一行解決方案可以是這樣的:
sum(sodf[!sodf$Area %in% stringr::str_replace_all(sodf[!grepl('0$',sodf$Area),"Area"],'[1-9]$','0') & !sodf$Area %in% sodf[grepl('^[0]+[1-9]{1}[0]+$',sodf$Area),"Area"] ,"Total"])
它是如何工作的?
sodf[,grepl('0$',sodf$Area),"Area"]
# "051043" "051053"stringr::str_replace_all(sodf[,grepl('0$',sodf$Area),"Area"],'[1-9]$','0')
# "051040" "051050"sum(sodf[:sodf$Area %in% stringr:,str_replace_all(sodf[,grepl('0$',sodf$Area),"Area"],'[1-9]$','0') &,sodf$Area %in% sodf[grepl('^[0]+[1-9]{1}[0]+$',sodf$Area),"Area"] ,"Total"] )
# 100使用 dplyr package 將代碼拆分為多行可以實現相同的結果。
我的同事建議了以下變體。
library(tidyverse)
check_diff <- function(df) {
# Find value Total, for instance ends with 0000
sum_control <- df |>
filter(str_detect(Area, "0{4}$")) |>
select(Total)
# Find second number from the end where the last character is 3 and connect them into one string
before_last_3 <- df |>
filter(str_detect(Area, "3$")) |>
pull(Area) |>
str_sub(-2, -2) |>
str_flatten()
# Create string for filter pattern
filter3 <- str_c("[", before_last_3, "]0$")
# filter data on new conditions and find sum
sum <- df |>
filter(!str_detect(Area, "0{4}$"),
!str_detect(Area, filter3)) |>
summarise(sum(Total))
sum_control - sum
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.