【问题标题】:Compute new rows in r data frame r based on existing rows and columns根据现有的行和列计算 r 数据框 r 中的新行
【发布时间】:2018-12-07 20:49:14
【问题描述】:

我希望能提示使用哪个命令来执行以下操作: 我想计算“名称”列中的城市和“年份”列中每年的人口估计值。 “增长”列提供增长率。所以公式会是这样的:

Population[Lucknow,2030] = Population[Lucknow, 2020] * growth[2030]

等等。跟随df:

df <- data.frame(YEAR=c(2020,2020,2020,2030,2040,2050), NAME=c("Lucknow","Delhi","Hyderadabad",NA,NA,NA), POPULATION=c(3704, 29274,10275,NA,NA,NA), growth=c(1.0,1.0,1.0,1.10,1.18,1.24))
Year                Name           Population        growth
2020             Lucknow                 3704     1.0000000
2020               Delhi                29274     1.0000000
2020           Hyderabad                10275     1.0000000
2030                <NA>                   NA   <NA> 1.10
2040                <NA>                   NA   <NA> 1.18
2050                <NA>                   NA   <NA> 1.24

编辑:按照 Dom(谢谢!)在下面写的内容,输入将是:

df <- tibble( year = rep(c(2020,2030,2040,2050), each = 3), city =rep(c("Lucknow","Delhi","Hyderadabad"), times = 4), pop = c(3704, 29274,10275, rep(NA_integer_, times = 9)), growth = rep(c(1.0, 1.10, 1.18, 1.24), each = 3) )
    year city          pop growth
   <dbl> <chr>       <dbl>  <dbl>
 1  2020 Lucknow      3704   1   
 2  2020 Delhi       29274   1   
 3  2020 Hyderadabad 10275   1   
 4  2030 Lucknow        NA   1.1 
 5  2030 Delhi          NA   1.1 
 6  2030 Hyderadabad    NA   1.1 
 7  2040 Lucknow        NA   1.18
 8  2040 Delhi          NA   1.18
 9  2040 Hyderadabad    NA   1.18
10  2050 Lucknow        NA   1.24
11  2050 Delhi          NA   1.24
12  2050 Hyderadabad    NA   1.24

输出应如下所示:

Year                Name           Population        growth
2020             Lucknow                 3704     1.0000000
2020               Delhi                29274     1.0000000
2020           Hyderabad                10275     1.0000000
2030             Lucknow               4074.4     1.1000000
2030               Delhi              32201.4     1.1000000
2030           Hyderabad              11302.5     1.1000000
....

如何在tibble中填写NAs?

我对 merge 和 dplyr::mutate 进行了各种尝试,但鉴于这是一个向量操作,我无法确定我需要在这里做什么。我很高兴能找到正确的命令来执行这样的基本操作。

谢谢!

【问题讨论】:

  • 我要睡觉了,但你的数据应该是这样的:df
  • 我认为这将是一个简单的 group_by 操作,但我一直无法找到简单的解决方案。
  • 谢谢你,多姆。我已将您的 tibble 建议包含在原始帖子中。那我该如何填写 NA 值呢? (我的原始数据集要大得多)

标签: r dataframe dplyr


【解决方案1】:

使用dplyr

library(dplyr)
df %>%
  arrange(city, year) %>%
  group_by(city) %>%
  mutate(pop = pop[1] * growth)

# A tibble: 12 x 4
# Groups:   city [3]
    year city           pop growth
   <dbl> <chr>        <dbl>  <dbl>
 1  2020 Delhi       29274    1   
 2  2030 Delhi       32201.   1.1 
 3  2040 Delhi       34543.   1.18
 4  2050 Delhi       36300.   1.24
 5  2020 Hyderadabad 10275    1   
 6  2030 Hyderadabad 11303.   1.1 
 7  2040 Hyderadabad 12124.   1.18
 8  2050 Hyderadabad 12741    1.24
 9  2020 Lucknow      3704    1   
10  2030 Lucknow      4074.   1.1 
11  2040 Lucknow      4371.   1.18
12  2050 Lucknow      4593.   1.24

使用基础R:

df <- df[order(df[["city"]], df[["year"]]), ]
df[["pop"]] <-
  unlist(
    lapply(
      unique(df[["city"]]), 
      function(x) with(df[df[["city"]] == x, ], pop[1] * growth)
    )
  )

使用data.table

library(data.table)
setDT(df)[order(city, year), pop := pop[1] * growth, city]

数据:

df <- tibble(
  year   = rep(c(2020, 2030, 2040, 2050), each = 3), 
  city   = rep(c("Lucknow", "Delhi", "Hyderadabad"), times = 4), 
  pop    = c(3704, 29274, 10275, rep(NA, times = 9)), 
  growth = rep(c(1.0, 1.10, 1.18, 1.24), each = 3)
)

【讨论】:

  • 太棒了,非常感谢。这个答案几乎是百科全书。我会将这些答案转移到我的原始数据中,并尝试列出的 dplyr 解决方案,与粘贴的其他解决方案非常相似。
【解决方案2】:

基准年总是 2020 年吗?如果是,则以下工作:

library(tidyverse)

df <- tibble( year = rep(c(2020, 2030, 2040, 2050), each = 3), 
              city = rep(c("Lucknow", "Delhi", "Hyderadabad"), times = 4), 
              pop = c(3704, 29274, 10275, rep(NA_integer_, times = 9)), 
              growth = rep(c(1.0, 1.10, 1.18, 1.24), each = 3) )

uniq <- unique(df$pop)
uniq <- uniq[!is.na(uniq)]

df$pop <- rep(uniq, length(unique(df$year)))

df <- df %>% 
  mutate(pop2 = pop * growth)

【讨论】:

  • 谢谢!在这里看到如何使用 mutate 很好,可以替代 join。
【解决方案3】:
library(tidyverse)
NAME <- c("Lucknow","Delhi","Hyderadabad")
YEAR <- seq(2020,2050,10)
POPULATION=rep(c(3704, 29274,10275),4)
pop_df <- bind_cols(expand.grid(Name=NAME,Year=YEAR),Population=POPULATION)
growth_df <- data.frame(Year=seq(2020,2050,10),growth=c(1,1.1,1.18,1.23))
pop_df <- left_join(pop_df,growth_df) %>%
  mutate(Population=round(Population*growth))

【讨论】:

  • 谢谢!这很好用,我可以看到我缺少的主要内容是正确的连接形式。
猜你喜欢
  • 2014-10-07
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
相关资源
最近更新 更多