将数据框两行变成一行

时间:2018-11-07 08:38:18

标签: r dataframe

我有一个数据帧,其中某些行是其他几行的后续操作(彼此完成),我想将它们合并成一行。请看下面的例子

+-------+-------------+-----------+-----+---------+
| rowID | name        | address   | age | firstId |
+-------+-------------+-----------+-----+---------+
| 1     | Bert        |           | 60  |         |
+-------+-------------+-----------+-----+---------+
| 2     | Ernie       | Berlin    | 72  |         |
+-------+-------------+-----------+-----+---------+
| 3     | Bert Sesame | Amsterdam |     | 1       |
+-------+-------------+-----------+-----+---------+

第三个rowId指向第一个RowId,这反过来又会使Bert变老60岁。同时,第二行没有firstId(需要跟进的行),应保留原样。

两行中都可以填写一些列,我想填写firstID字段已填写的行(因此是最新行)。例如,第三行的名称为“ Bert Sesame”,在这种情况下,我想使用名称“ bert sesame”,即具有firstId值的行。

最终数据帧为

+-------+-------------+-----------+-----+---------+
| rowID | name        | address   | age | firstId |
+-------+-------------+-----------+-----+---------+
| 2     | Ernie       | Berlin    | 72  |         |
+-------+-------------+-----------+-----+---------+
| 3     | Bert Sesame | Amsterdam | 60  | 1       |
+-------+-------------+-----------+-----+---------+

我该如何实现?

我看过这样的问题。 Merge two rows in data.frame

但这是通过将所有行分组在一起来指代所有行。我只想合并/合并专门引用其他行的行。

1 个答案:

答案 0 :(得分:0)

这里尝试使用tidyverse

library(tidyverse)

df %>% 
 group_by(rowID_new = replace(rowID, firstId != '', firstId[firstId != ''])) %>% 
 mutate(age = replace(age, age == '', age[age != ''])) %>% 
 ungroup() %>% 
 filter(!rowID %in% firstId) %>% 
 select(-rowID_new)

给出,

# A tibble: 2 x 5
  rowID name  address age   firstId
  <dbl> <chr> <chr>   <chr> <chr>  
1     2 B     E       72    ""     
2     3 C     F       60    1

编辑: 如果您要填充多个变量,我们可以将''替换为NA并使用fill,即

df %>% 
 mutate_all(function(i) replace(i, i == '', NA)) %>% 
 group_by(rowID_new = replace(rowID, !is.na(firstId), firstId[!is.na(firstId)])) %>% 
 fill(-rowID, .direction = 'up') %>% #you might not need this[with .direction = 'up']
 fill(-rowID) %>% 
 ungroup() %>% 
 filter(!rowID %in% firstId)

给出,

# A tibble: 2 x 6
  rowID name  address age   firstId rowID_new
  <dbl> <chr> <chr>   <chr> <chr>   <chr>    
1     3 C     F       60    1       1        
2     2 B     E       72    <NA>    2

已使用示例

structure(list(rowID = c(1, 2, 3), name = c("A", "B", "C"), address = c("D", 
"E", "F"), age = c("60", "72", ""), firstId = c("", "", "1")), class = "data.frame", row.names = c(NA, 
-3L))