[英]Merging rows of dataframe based on unique ID
我有一個數據框,其中所有參與者的唯一主題 ID 重復兩次。 下面的數據似乎包含一列,其中一個條目的值為 NA,其中一個條目有一個值的一列(盡管這不確定,我使用的方法應該考慮到這不是真的)。 這是一個例子:
Name <- c("Jon", "Jon", "Maria", "Maria", "Tina", "Tina", "dan", 'dan', 'wen', 'wen')
a <- c(1, 1, 2, 2, 3, 4, 4, 4, 5, 6)
b <- c(NA, 1, NA, 2, NA, 3, NA, 4, NA, 5)
c <- c(1, NA, 2, NA, 3, NA, 4, NA, 5, NA)
df <- data.frame(Name, a, b, c)
到目前為止,我想到的解決方案包括遍歷所有唯一 ID(在上面的示例中為名稱)並為每個條目制作單獨的數據幀。 像這樣的東西:
#Instantiate list of lists that will become dfs
firstdf <- c()
seconddf <- c()
#Loop through existing df by unique ID (Name) and create
# list containing values of 1 entry and list of the other
for (i in unique(df$Name)) {
innerlist1 <- c()
innerlist2 <- c()
for (x in c(1:length(df[df['Name'] == i]))) {
if (x%%2 == 1) {
# Takes one set of entries per ID
innerlist1 <- c(innerlist1, df[df['Name'] == i][x])
} else if (x%%2 == 0) {
# Takes other set of entries per ID
innerlist2 <- c(innerlist2, df[df['Name'] == i][x])
}
}
firstdf <- c(firstdf, list(innerlist1))
seconddf <- c(seconddf, list(innerlist2))
}
# Make dfs from lists
firstdf <- do.call(rbind.data.frame, firstdf)
names(firstdf) <- names(df)
seconddf <- do.call(rbind.data.frame, seconddf)
names(seconddf) <- names(df)
然后,我將繼續使用合並之類的方法將 dfs 與by="Name"
結合起來。 我的原始數據集很大,這不是特別有效或優雅。 任何人都可以提出改進建議嗎?
您可以通過排除NA
的組來保留第一個值:
library(dplyr)
df %>%
group_by(Name) %>%
summarise(a = first(stats::na.omit(a)),
b = first(stats::na.omit(b)),
c = first(stats::na.omit(c)))
# A tibble: 5 x 4
Name a b c
<chr> <dbl> <dbl> <dbl>
1 dan 4 4 4
2 Jon 1 1 1
3 Maria 2 2 2
4 Tina 3 3 3
5 wen 5 5 5
如果每個 ID 有多個非 NA 值,您可以將它們集中到toString
。 您可以使用以下代碼:
library(dplyr)
df %>%
group_by(Name) %>%
summarise_all(funs(toString(na.omit(.))))
輸出:
# A tibble: 5 × 4
Name a b c
<chr> <chr> <chr> <chr>
1 dan 4, 4 4 4
2 Jon 1, 1 1 1
3 Maria 2, 2 2 2
4 Tina 3, 4 3 3
5 wen 5, 6 5 5
順便說一句,對於未來的讀者,我最終做的是通過奇數/偶數索引獲取每個 ID 的每個條目,並制作兩個數據幀,如下所示:
firstdf <- df[seq_len(nrow(df))%%2 == 1, ]
seconddf <- df[seq_len(nrow(df))%%2 == 0, ]
在此之后,只需刪除所有條目都是 NA 的列,然后合並 dfs,同時處理兩個 dfs 在同一位置相應地具有非 NA 值的情況(例如,通過取兩個值的平均值) .
在我的現實生活中,我還必須采取一些額外的步驟,但這個例子的簡單性並沒有體現出來,包括:
df <- df[order(df$Name), ]
rownames(df) <- NULL
#Using dplyr
library(dplyr)
df %>%
count(Name) %>%
filter(n!=2)
# Should return 0 rows
在條目多於或少於兩個的情況下,我執行了以下操作:
more <- df %>%
count(name) %>%
filter(n>2)
df_more_than_two <- df[df$Name %in% more$Name]
# Change sign in filter function to < 2 for those with only one entry
然后我制作了三個數據框(那些有 1 個條目,那些有 2 個條目,還有那些有 3 個條目),但基本上執行了相同的步驟
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.