如何用R函数逆转cumsum()还原数据集的原始非累积列?
Hey there! Let's break down how to reverse the cumsum() operation to recover your original visits column from the grouped cumulative dataset DFc, plus cover how to adjust this for weekly date intervals.
1. Reverting cumsum() for Daily Data (Your Original Case)
Since your cumulative values are grouped by country, we need to maintain that grouping when reversing the calculation. The trick is to subtract the previous row's cumulative value from the current row's cumulative value. For the first row in each group (where there's no previous value), we'll use 0 as the default to get the original first visits value directly.
Here's the code:
# Load dplyr if you haven't already library(dplyr) # Restore the original visits column from DFc DF_restored <- DFc %>% group_by(country) %>% mutate(visits = cumulative_visits - lag(cumulative_visits, default = 0)) %>% ungroup() # Optional: remove grouping if you don't need it anymore
How this works:
lag(cumulative_visits, default = 0)shifts the cumulative values up by one row within each country group. Thedefault = 0ensures the first row doesn't returnNA—instead, we subtract 0 to get the initialvisitsvalue.- Subtracting this lagged value from the current cumulative value gives you exactly the incremental visits for that period, which is your original
visitsdata.
You can verify this works perfectly with your sample data:
# Check if restored visits match the original DF all.equal(DF_restored$visits, DF$visits) # Returns TRUE
2. Adjusting for Weekly Date Intervals
The core logic stays the same—the key is ensuring your data is sorted correctly by date within each group, regardless of whether it's daily or weekly. Here's what you need to do:
First, make sure your date column is in a sortable date format (not just a string). For weekly dates, you can use formats like yearweek (from the lubridate package) or standard Date objects (if your weekly dates are tied to a specific day like the end of the week).
Example code for weekly data:
library(dplyr) library(lubridate) # For handling weekly dates # Assume DFc_weekly has weekly dates (e.g., "2020-W01", "2020-W02") DF_restored_weekly <- DFc_weekly %>% # Convert weekly date strings to a sortable yearweek format mutate(date = yearweek(date)) %>% group_by(country) %>% arrange(date) %>% # Critical: ensure rows are ordered chronologically mutate(visits = cumulative_visits - lag(cumulative_visits, default = 0)) %>% ungroup()
Important note:
Even if your weekly dates are stored as strings like "2020-01-10" (representing the end of week 2), as long as you convert them to a proper Date type and sort within each group, the same lag-and-subtract method will work. The frequency of the dates doesn't change the reversal logic—only the ordering matters.
内容的提问来源于stack exchange,提问作者kiwi

