我有一个数据帧,其中一些行是其他行的后续行(相互补充(,我想将这些行合并为一行。以为例
+-------+-------------+-----------+-----+---------+
| rowID | name | address | age | firstId |
+-------+-------------+-----------+-----+---------+
| 1 | Bert | | 60 | |
+-------+-------------+-----------+-----+---------+
| 2 | Ernie | Berlin | 72 | |
+-------+-------------+-----------+-----+---------+
| 3 | Bert Sesame | Amsterdam | | 1 |
+-------+-------------+-----------+-----+---------+
第三行Id指的是第一行Id,这反过来又会使伯特60岁。同时,第二行没有firstId(要跟进的行(,应该保持原样。
有些列可以在两行中都填写,我想选择填写了firstID字段的行(因此是最新的行(。例如,第三行的名称为"Bert-Sesame",在这种情况下,我想使用名称"Bert-芝麻",该行具有firstId值。
最终数据帧将是
+-------+-------------+-----------+-----+---------+
| rowID | name | address | age | firstId |
+-------+-------------+-----------+-----+---------+
| 2 | Ernie | Berlin | 72 | |
+-------+-------------+-----------+-----+---------+
| 3 | Bert Sesame | Amsterdam | 60 | 1 |
+-------+-------------+-----------+-----+---------+
我该如何做到这一点?
我研究过这样的问题。合并数据中的两行。帧
但这是通过将所有行分组在一起来引用它们的。我只想合并/组合专门引用其他行的行。
下面是一个使用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))