kem*_*uan 5 r data-manipulation
我有一个数据框,其中每一行代表一个空间单元。nbid* 变量指示哪个单元是邻居。我想将邻居的虚拟变量放入主数据框中。(它可以不是空间单位,而是数据框架内的任何类型的关系 - 业务合作伙伴、亲戚、相关基因等。)一些简化的数据如下所示:
seed(999)
df_base <- data.frame(id = seq(1:100),
dum= sample(c(rep(0,50), rep(1,50)),100),
nbid_1=sample(1:100,100),
nbid_2=sample(1:100,100),
nbid_3=sample(1:100,100)) %>%
mutate(nbid_1 = replace(nbid_1, sample(row_number(), size = ceiling(0.1 * n()), replace = FALSE), NA),
nbid_2 = replace(nbid_2, sample(row_number(), size = ceiling(0.3 * n()), replace = FALSE), NA),
nbid_3 = replace(nbid_3, sample(row_number(), size = ceiling(0.7 * n()), replace = FALSE), NA))
Run Code Online (Sandbox Code Playgroud)
(在这些简化数据中以及除了真实数据之外,邻居 1,2 和 3 可以相同,但这对于问题来说并不重要。)
我的方法是复制然后连接数据,如下所示:
df1 <- df_base
df2 <- df_base %>%
select(-c(nbid_1,nbid_2,nbid_3)) %>%
rename(nbdum=dum)
df <- left_join(df1,df2,by=c("nbid_1"="id")) %>%
rename(nbdum1=nbdum) %>%
left_join(.,df2,by=c("nbid_2"="id")) %>%
rename(nbdum2=nbdum) %>%
left_join(.,df2,by=c("nbid_3"="id")) %>%
rename(nbdum3=nbdum)
Run Code Online (Sandbox Code Playgroud)
df是我正在寻找的结果 - 从这里我可以创建一个整体邻居虚拟或计数。然而,对于具有更多邻居的真实数据来说,这种方法既不优雅也不可行。
我怎样才能以不那么笨拙的方式解决这个问题?
预先感谢您的想法!
一个关键线索是,当您看到 时var_1, var_2, ..., var_n,表明数据可以转换得更长。请参阅pivot_longer()或经常讨论数据的data.table::melt()地方。molten
对于您的示例,我们可以先进行旋转,然后再将df2表连接回来。我不确定是否需要该格式,但在加入后,我们可以使用 转回宽格式pivot_wider()。
library(dplyr)\nlibrary(tidyr)\n\n\ndf1 %>%\n select(!id) %>%\n pivot_longer(cols = starts_with("nbid"), names_prefix = "nbid_")%>%\n mutate(original_id = rep(1:100, each = 3))%>%\n left_join(df2, by = c("value" = "id"))%>%\n pivot_wider(original_id, values_from = c(value, nbdum))\n\n#> # A tibble: 100 \xc3\x97 7\n#> original_id value_1 value_2 value_3 nbdum_1 nbdum_2 nbdum_3\n#> <int> <int> <int> <int> <dbl> <dbl> <dbl>\n#> 1 1 25 90 23 0 0 1\n#> 2 2 12 NA NA 1 NA NA\n#> 3 3 11 40 47 0 0 0\n#> 4 4 94 87 NA 0 1 NA\n#> 5 5 46 77 NA 1 0 NA\n#> 6 6 98 82 NA 1 0 NA\n#> 7 7 43 NA NA 1 NA NA\n#> 8 8 74 NA 7 0 NA 1\n#> 9 9 57 NA NA 1 NA NA\n#> 10 10 49 72 NA 0 0 NA\n#> # \xe2\x80\xa6 with 90 more rows\n\n## compare to original\n\nas_tibble(df)\n#> # A tibble: 100 \xc3\x97 8\n#> id dum nbid_1 nbid_2 nbid_3 nbdum1 nbdum2 nbdum3\n#> <int> <dbl> <int> <int> <int> <dbl> <dbl> <dbl>\n#> 1 1 0 25 90 23 0 0 1\n#> 2 2 1 12 NA NA 1 NA NA\n#> 3 3 1 11 40 47 0 0 0\n#> 4 4 1 94 87 NA 0 1 NA\n#> 5 5 0 46 77 NA 1 0 NA\n#> 6 6 1 98 82 NA 1 0 NA\n#> 7 7 1 43 NA NA 1 NA NA\n#> 8 8 0 74 NA 7 0 NA 1\n#> 9 9 0 57 NA NA 1 NA NA\n#> 10 10 0 49 72 NA 0 0 NA\n#> # \xe2\x80\xa6 with 90 more rows\nRun Code Online (Sandbox Code Playgroud)\n