如何为R中的每个不同列选择不同行中的值?

时间:2018-06-29 20:56:32

标签: r dplyr tidyr

我有两个数据框,data1与孩子的年龄有关。对于不同的年份,值是不同的。

data2仍然是每个年龄的人口数据,列名仍然是year。

我想要的是将人口信息提取到一个新的数据框中。但对于2008/2009/2010年,人口数据应来自7岁至10岁。但对于2011/2012/2013,人口数据应来自6岁至9岁。

有人知道吗?

db.lfm_case.ALL

4 个答案:

答案 0 :(得分:2)

在我看来您想要其中之一:

library(tidyverse)

data2 %>%
  gather(year,value,-population.by.age) %>%
  inner_join(gather(data1,year,population.by.age)) %>%
  spread(year,value)

# population.by.age  X2008  X2009  X2010  X2011  X2012  X2013
# 1                 6     NA     NA     NA 151387 129737 116093
# 2                 7 136150 139367 142555 146491 126124 112666
# 3                 8 131944 135083 138172 141905 122678 109174
# 4                 9 198933 212196 218701 119397 120213 106871
# 5                10 182182 196398 161330     NA     NA     NA


data2 %>%
  gather(year,value,-population.by.age) %>%
  inner_join(gather(data1,year,population.by.age)) %>%
  group_by(year) %>%
  mutate(population.by.age = letters[row_number()]) %>%
  spread(year,value)

# # A tibble: 4 x 7
# population.by.age  X2008  X2009  X2010  X2011  X2012  X2013
# <chr>              <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
# 1 a                 136150 139367 142555 151387 129737 116093
# 2 b                 131944 135083 138172 146491 126124 112666
# 3 c                 198933 212196 218701 141905 122678 109174
# 4 d                 182182 196398 161330 119397 120213 106871

这是第二种情况的基本版本,无需经过长期/广泛的重新制定:

data3 <- data1
data3[] <- Map(function(x,y) y[data2[[1]] %in% x,drop=FALSE],data1,data2[-1])
data3
#    X2008  X2009  X2010  X2011  X2012  X2013
# 1 136150 139367 142555 151387 129737 116093
# 2 131944 135083 138172 146491 126124 112666
# 3 198933 212196 218701 141905 122678 109174
# 4 182182 196398 161330 119397 120213 106871

答案 1 :(得分:1)

我们可以将第二个数据集dask.compute转换为“长”格式,gather根据条件,filter转换为“宽”格式

spread

答案 2 :(得分:0)

它不是很优雅,但是您可以尝试以下方法:

aux <- data2 %>% 
  select(population.by.age,X2008,X2009,X2010) %>% 
  filter(population.by.age > 6, 
         population.by.age < 10)


aux2 <- data2 %>% 
  select(population.by.age,X2011,X2012,X2013) %>% 
  filter(population.by.age > 5, 
         population.by.age < 9)

df <- full_join(aux,aux2) %>% 
  arrange(population.by.age)

祝你好运!

答案 3 :(得分:0)

使用tidyverse

stack(data1)%>%
   mutate(val=data2[cbind(match(values,data2[,1]),as.numeric(ind))])%>%
   spread(ind,val)

  values X2008  X2009  X2010  X2011  X2012  X2013
1      6    NA     NA     NA 147261 151387 129737
2      7     7 136150 139367 142555 146491 126124
3      8     8 131944 135083 138172 141905 122678
4      9     9 198933 212196 218701 119397 120213
5     10    10 182182 196398     NA     NA     NA

使用基数R:

xtabs(val~.,cbind(a<-stack(data1),val=data2[cbind(a$values-4,as.numeric(a$ind))]))
      ind
values  X2008  X2009  X2010  X2011  X2012  X2013
    6       0      0      0 147261 151387 129737
    7       7 136150 139367 142555 146491 126124
    8       8 131944 135083 138172 141905 122678
    9       9 198933 212196 218701 119397 120213
    10     10 182182 196398      0      0      0