r - 使用列值在数据框中创建新行

标签 r dataframe

我正在尝试通过从列值创建新行来格式化 R 中的凌乱数据帧。数据片段如下所示。

id  producer  pcountry  collaborator  ccountry   val
1    J&J       USA        Pfizer       USA       25

2    Biodiem   AUS        PhaseBio     USA       65
                          GeneScience  China     

3    Shire     Ireland       N/A        N/A      54

4    Sanofi    France        N/A        N/A      64

本质上,我想使用最后两列中的值在数据框中创建新行。到目前为止,我有这段代码,使用 splitstackshape包。

df2 <- cSplit(df, 4, "\r", "long")

此操作适用于协作者列中具有多个值的条目(如上面的第 2 行)。使用我的代码给了我这个:`

id  producer  pcountry  collaborator  ccountry   val
1    J&J       USA        Pfizer       USA       25

2    Biodiem   AUS        PhaseBio     USA       65
                                       China     

3    Biodiem   AUS        Genescience  USA       65
                                       China

4    Shire     Ireland       N/A        N/A      54

5    Sanofi    France        N/A        N/A      64

但是,我还想用我正在处理的数据做更多的事情。我希望 collaborator 列的值与 ccountry 列的值匹配,因此此处第 3 行的值将为 Chinaccountry列,而第 2 行将有 USA 。我尝试在代码中添加两列,如下所示 df2 <- cSplit(df, c(4,5), "\r", "long") ,但这只会弄得一团糟。

最后,由于代码仅使用新行分隔符创建新条目,因此它会忽略那些只有 1 个值的条目(如第 1 行),因为它们没有新行。我希望这些也包括在内。

有什么方法可以更改此代码以执行这两个额外步骤,或者我必须为此编写一个函数吗?

编辑:这是数据片段

     id producer pcountry collaborator              ccountry         val
  <dbl> <chr>    <chr>    <chr>                     <chr>          <dbl>
1     1 J&J      USA      Pfizer                    USA               25
2     2 Biodiem  AUS      "PhaseBio\r\nGenescience" "USA\r\nChina"    65
3     3 Shire    Ireland  NA                        NA                54
4     4 Sanofi   France   NA                        NA                64
structure(list(id = c(1, 2, 3, 4), producer = c("J&J", "Biodiem", 
"Shire", "Sanofi"), pcountry = c("USA", "AUS", "Ireland", "France"
), collaborator = c("Pfizer", "PhaseBio\r\nGenescience", NA, 
NA), ccountry = c("USA", "USA\r\nChina", NA, NA), val = c(25, 
65, 54, 64)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", 
"data.frame"))

这是预期的结果

     id producer pcountry collaborator ccountry   val
  <dbl> <chr>    <chr>    <chr>        <chr>    <dbl>
1     1 J&J      USA      NA           NA          25
2     2 J&J      USA      Pfizer       USA         25
3     3 Biodiem  AUS      NA           NA          65
4     4 Biodiem  AUS      PhaseBio     USA         65
5     5 Biodiem  AUS      Genescience  China       65
6     6 Shire    Ireland  NA           NA          54
7     7 Sanofi   France   NA           NA          64
structure(list(id = c(1, 2, 3, 4, 5, 6), producer = c("J&J", 
"J&J", "Biodiem", "Biodiem", "Biodiem", "Shire"), pcountry = c("USA", 
"USA", "AUS", "AUS", "AUS", "Ireland"), collaborator = c(NA, 
"Pfizer", NA, "PhaseBio", "Genescience", NA), ccountry = c(NA, 
"USA", NA, "USA", "China", NA), val = c(25, 25, 65, 65, 65, 54
)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
)) 

最佳答案

使用 tidyr 非常简单:

require(tidyr)
separate_rows(df, collaborator,ccountry, sep="\r\n")

# A tibble: 5 x 6
     id producer pcountry collaborator ccountry   val
  <dbl> <chr>    <chr>    <chr>        <chr>    <dbl>
1     1 J&J      USA      Pfizer       USA         25
2     2 Biodiem  AUS      PhaseBio     USA         65
3     2 Biodiem  AUS      Genescience  China       65
4     3 Shire    Ireland  NA           NA          54
5     4 Sanofi   France   NA           NA          64

如果您想要所有这些额外的行都包含协作者和国家/地区的 NA,您可以执行以下操作:

require(tidyr)
require(dplyr)
df %>% mutate(collaborator=ifelse(is.na(collaborator), NA, paste0("\r\n",collaborator)), 
    ccountry=ifelse(is.na(ccountry), NA, paste0("\r\n",ccountry))) %>% # Create extra rows before non NA rows
  separate_rows(collaborator,ccountry, sep="\r\n") %>% 
  mutate(collaborator=ifelse(collaborator=="",NA,collaborator), 
    ccountry=ifelse(ccountry=="", NA, ccountry)) # change empty strings to NAs
# A tibble: 7 x 6
     id producer pcountry collaborator ccountry   val
  <dbl> <chr>    <chr>    <chr>        <chr>    <dbl>
1     1 J&J      USA      NA           NA          25
2     1 J&J      USA      Pfizer       USA         25
3     2 Biodiem  AUS      NA           NA          65
4     2 Biodiem  AUS      PhaseBio     USA         65
5     2 Biodiem  AUS      Genescience  China       65
6     3 Shire    Ireland  NA           NA          54
7     4 Sanofi   France   NA           NA          64

关于r - 使用列值在数据框中创建新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55632726/

相关文章:

r - 创建一个按组捕获最频繁出现的变量

r - ggfortify::autoplot 或 ggfortify::::autoplot 不工作

python - Pandas 数据框中每两列的总和

python - 用 Panadas 按一列比较两个 DataFrame 并返回三个不同的输出

hadoop - Spark ml 模型保存到 hdfs

r - 我可以编辑某种类型的 R Studio 配置文件而不是通过 GUI 更改所有选项吗?

循环运行 H2O 的 Auto ML

r - R 中的 log10 转换

Python:如何在特定时间窗口内对 pandas Data Frame 进行分组?

python - 计算 Pandas 中具有相同列值的行的平均值