【问题标题】:Mapping values across a dataframe跨数据框映射值
【发布时间】:2018-11-28 04:22:25
【问题描述】:

我有一个大型数据集。下面的例子是一个大大简化的版本。

有两个数据框,df1 和 df2。我想映射到 df1 的每一行,这是一个使用 df2 条件和 df1 参数的派生值。

希望下面的例子更有意义

year <- rep(1996:1997, each=3)
age_group <- rep(c("20-24","25-29","30-34"),2)
df1 <- as.data.frame(cbind(year,age_group))

df1 是一个包含所有年份和年龄组排列的数据库。

df2 <- as.data.frame(rbind(c(111,1997,"20-24"),c(222,1997,"30-34")))
names(df2) <- c("id","year","age.group")

df2 是一个数据库,其中每一行代表特定年份的个人

我想使用 df1 中的参数,条件是 df2 中的值,然后映射到 df1。论据如下:

each_yr <- map(df1, function(year,age_group) case_when(
as.character(df1$year) == as.character(df2$year) & as.character(df1$age_group)    
== as.character(df2$age.group)~ 0, 
TRUE ~ 1))

我得到的输出是错误的,如下所示

structure(list(year = c(1, 1, 1, 1, 1, 0), age_group = c(1, 1, 
1, 1, 1, 0)), .Names = c("year", "age_group")) 

我最喜欢的输出是这样的(以数据框为例,但作为列表会很高兴)

structure(list(year = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("1996", 
"1997"), class = "factor"), age_group = structure(c(1L, 2L, 3L, 
1L, 2L, 3L), .Label = c("20-24", "25-29", "30-34"), class = "factor"), 
v1 = structure(c(2L, 2L, 2L, 1L, 2L, 2L), .Label = c("0", 
"1"), class = "factor"), v2 = structure(c(2L, 2L, 2L, 2L, 
2L, 1L), .Label = c("0", "1"), class = "factor")), .Names = c("year", 
"age_group", "v1", "v2"), row.names = c(NA, -6L), class = "data.frame")

我之前在“df1”是向量时使用过 map,但在这种情况下,它是一个数据框,其中两列都用作参数。地图可以处理吗?

在 df3 中,列 v1 是基于 df1 和 df2 的条件的结果,然后映射到患者“111”的 df1。同样,第 v2 列是患者“222”的结果。

提前致谢

【问题讨论】:

  • 您使用的是哪些软件包?具体来说,哪个map-function?它不是基础R
  • Purrr 包作为 tidyverse 生态系统的一部分

标签: r


【解决方案1】:

tidiverse 你可以这样做:

library(tidyverse)
#library(dplyr)
#library(tidyr)

df2 %>%
  mutate(tmp = 0) %>%
  spread(id, tmp, fill = 1, sep = "_") %>%
  right_join(df1, by = c("year", "age.group" = "age_group")) %>%
  mutate_at(vars(-c(1, 2)), coalesce, 1)

#   year age.group id_111 id_222
# 1 1996     20-24      1      1
# 2 1996     25-29      1      1
# 3 1996     30-34      1      1
# 4 1997     20-24      0      1
# 5 1997     25-29      1      1
# 6 1997     30-34      1      0

#Warning messages:
# 1: Column `year` joining factors with different levels, coercing to character vector 
# 2: Column `age.group`/`age_group` joining factors with different levels, coercing to 
#    character vector 

【讨论】:

    【解决方案2】:

    看起来像是 pmap 的一些工作。稍微整理一下即可获得建议的结果。

    purrr::pmap(list(df2$id,as.character(df2$year),as.character(df2$age.group)),
      function(id,x,y)
       data.frame(df1,
                  key=paste0("v",id),
                  value=1-as.integer((x==df1$year)&(y==df1$age_group)),
                  stringsAsFactors=FALSE
              )) %>%
       replyr::replyr_bind_rows() %>% tidyr::spread(key,value)
    
    #  year age_group v1 v2
    #1 1996     20-24  1  1
    #2 1996     25-29  1  1
    #3 1996     30-34  1  1
    #4 1997     20-24  0  1
    #5 1997     25-29  1  1
    #6 1997     30-34  1  0
    

    【讨论】:

    • 天才 - 工作就像一个魅力。非常感谢 Nicolas2
    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 2011-06-06
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    相关资源
    最近更新 更多