簡體   English   中英

R:在數據框的列之間添加插值?

[英]R: Add interpolated values in between columns of dataframe?

我有一個看起來像這樣的數據框

Region      2000    2001   2002    2003    2004      2005
Australia   15.6    18.4   19.2    20.2    39.1      50.2
Norway      19.05   20.2   15.3    10      10.1      5.6

基本上我需要一種快速的方法來在包含周圍列的插值的當前現有列之間添加額外的列。

可以這樣想:假設您不想要每年的列,而是每個季度的列。 然后,對於每一對年份(如 2000 年和 2001 年),我們需要在這些年份之間添加 3 個額外的列。

這些列的值只是內插值。 因此,對於澳大利亞,2000 年的值為 15.6,2001 年為 18.4。 所以我們計算 (18.4 - 15.6)/4 = 0.7,然后值現在應該是 15.6、16.3、17、17.7,最后是 18.4。

我有一個工作解決方案,它使用 for 循環從頭開始構建新的數據框。 它非常慢。 如何加快速度?

當我遇到類似問題時,我就是這樣做的。 不是最復雜的解決方案,但它有效。

Australia=c(  15.6,  18.4,  19.2,  20.2,   39.1,     50.2)

library(zoo)
midpoints=rollmean(Australia, 2)
biyearly=c(rbind(Australia,midpoints))
midpoints=rollmean(biyearly, 2)
quarterly=c(rbind(biyearly,midpoints))
quarterly
#[1] 15.600 16.300 17.000 17.700 18.400 18.600 18.800 19.000 19.200 19.450 19.700
#[12] 19.950 20.200 24.925 29.650 34.375 39.100 41.875 44.650 47.425 50.200 33.600
#[23] 17.000 16.300

這是使用 dplyr 的解決方案。 應該比循環更一致和更快:

# dummy data
df <- tibble(Region = LETTERS[1:5],
             `2000` = 1:5,
             `2001` = 3:7,
             `2002` = 10:14)

# function to calculate quarterly values
into_quarter <- function(x) x / 4

df %>% 
  # create new variables that contain quarterly values
  mutate_at(vars(starts_with("200")), 
            .funs = list("Q1" = into_quarter,
                         "Q2" = into_quarter,
                         "Q3" = into_quarter,
                         "Q4" = into_quarter)) %>% 
  # sort them approriatly.
  # can also be done with base R and order(names), depending on desired result
  select(Region, 
         starts_with("2000"),
         starts_with("2001"),
         starts_with("2002"),
         # in case there are also other variables and to not loose any information
         everything())

這是tidyverse一種方式:

library(tidyverse)

df %>%
  #get data in long format
  pivot_longer(cols = -Region) %>%
  #group by Region
  group_by(Region) %>%
  #Create 4 number sequence between every 2 value
  summarise(temp = list(unlist(map2(value[-n()], value[-1], seq, length.out = 4)))) %>%
  #Get data in long format
  unnest(temp) %>%
  group_by(Region) %>%
  #Create column name
  mutate(col = paste0(rep(names(df)[-c(1, ncol(df))], each = 4), "Q", 1:4)) %>%
  #Spread data in wide format
  pivot_wider(names_from = col, values_from = temp)

# A tibble: 2 x 21
# Groups:   Region [2]
#  Region `2000Q1` `2000Q2` `2000Q3` `2000Q4` `2001Q1` `2001Q2` `2001Q3` `2001Q4` `2002Q1`
#  <fct>     <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
#1 Austr…     15.6     16.5     17.5     18.4     18.4     18.7     18.9     19.2     19.2
#2 Norway     19.0     19.4     19.8     20.2     20.2     18.6     16.9     15.3     15.3
# … with 11 more variables: `2002Q2` <dbl>, `2002Q3` <dbl>, `2002Q4` <dbl>,
#   `2003Q1` <dbl>, `2003Q2` <dbl>, `2003Q3` <dbl>, `2003Q4` <dbl>, `2004Q1` <dbl>,
#   `2004Q2` <dbl>, `2004Q3` <dbl>, `2004Q4` <dbl>

數據

df <- structure(list(Region = structure(1:2, .Label = c("Australia", 
"Norway"), class = "factor"), `2000` = c(15.6, 19.05), `2001` = c(18.4, 
20.2), `2002` = c(19.2, 15.3), `2003` = c(20.2, 10), `2004` = c(39.1, 
10.1), `2005` = c(50.2, 5.6)), class = "data.frame", row.names = c(NA, -2L))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM