如何基于R中的行值在data.frame中创建新列?

时间:2019-11-17 23:24:42

标签: r dplyr transformation splitstackshape

嘿,

我有一个带家庭三重奏的data.frame,我想添加一列,其中包含每个“ id”(=后代)的完整同胞。

我的数据:

df
         id    dam    sire
1:    83295  67606   79199
2:    83297  67606   79199
3:    89826  67606   79199

我要检索的内容:

df2
         id    dam    sire     fs1     fs2
1:    83295  67606   79199   83297   89826  
2:    83297  67606   79199   83295   89826  
3:    89826  67606   79199   83295   83297  

我尝试过的事情:

(类似于:How to transform a dataframes row into columns in R?

library(dplyr)
library(splitstackshape)

df2 <- df %>%
  group_by(dam,sire) %>%
  summarise(id = toString(id)) %>%
  cSplit("id") %>%
  setNames(paste0("fs_", 1:ncol(.)))

colnames(df2) <- c("dam", "sire", "id", "fs1", "fs2")

每个父母二人组只给我一行(而不是每个“ id”都创建同一行):

df2
     dam    sire       id      fs1     fs2
1: 67606   79199    83295    83297    89826  

在某些情况下,没有完整的同胞,在某些情况下,将有15个同胞。

在此先感谢您的建议! :)

1 个答案:

答案 0 :(得分:1)

我们可以group_by damsire使用id's获得除当前id以外的所有setdiff,然后使用cSplit将逗号分隔的值分成不同的列。

library(splitstackshape)
library(dplyr)

df %>%
  group_by(dam, sire) %>%
  mutate(fs = purrr::map_chr(id, ~toString(setdiff(id, .x)))) %>%
  cSplit("fs")

#      id   dam  sire  fs_1  fs_2
#1: 83295 67606 79199 83297 89826
#2: 83297 67606 79199 83295 89826
#3: 89826 67606 79199 83295 83297

数据

df <- structure(list(id = c(83295L, 83297L, 89826L), dam = c(67606L, 
67606L, 67606L), sire = c(79199L, 79199L, 79199L)), class = "data.frame",
row.names = c("1:", "2:", "3:"))