[英]Merge rows with similar information
我有几行数据框,我需要合并具有相同ID的行。
a=read.csv("a.csv")
view(a)
ID Value1 Value2 Value3 Value4 Value5 Value6
1076 2940 NA NA 2 NA NA
1076 2940 1 A- NA 302 549
1109 2940 NA NA 3 NA NA
1109 2940 NA A- NA 700 150
我需要这样的结果
ID Value1 Value2 Value3 Value4 Value5 Value6
1076 2940 1 A- 2 302 549
1109 2940 NA A- 3 700 150
我已经查看了类似问题的答案( 合并具有共享信息的行 )。 但是我得到的结果是错误的。
library(dplyr)
f <- function(x) {
x <- na.omit(x)
if (length(x) > 0) paste(x,collapse='-') else NA
}
a_merge <- a %>% group_by(ID)%>%summarise_all(list(f))
但是我收到以下错误
Error: Column `Value2` can't promote group 1 to character
请帮忙。
一种选择是创建符合条件if/else
返回NA当列中所有值是NA
或else
获得unique
的非NA的元素list
library(dplyr)
a %>%
group_by(ID) %>%
summarise_all(list(~ list(if(all(is.na(.))) NA else unique(.[!is.na(.)]))))
# A tibble: 2 x 7
# ID Value1 Value2 Value3 Value4 Value5 Value6
# <int> <list> <list> <list> <list> <list> <list>
#1 1076 <int [1]> <int [1]> <chr [1]> <int [1]> <int [1]> <int [1]>
#2 1109 <int [1]> <lgl [1]> <chr [1]> <int [1]> <int [1]> <int [1]>
编辑:
1)包装在list
2)@格雷戈尔的评论-只得到unique
非NA元素
a <- structure(list(ID = c(1076L, 1076L, 1109L, 1109L), Value1 = c(2940L,
2940L, 2940L, 2940L), Value2 = c(NA, 1L, NA, NA), Value3 = c(NA,
"A-", NA, "A-"), Value4 = c(2L, NA, 3L, NA), Value5 = c(NA, 302L,
NA, 700L), Value6 = c(NA, 549L, NA, 150L)), class = "data.frame", row.names = c(NA,
-4L))
这是基本的R方法,
setNames(do.call(rbind.data.frame, lapply(split(df, df$ID), function(i)
sapply(i, function(j) j[!is.na(j)][1]))), names(df))
# ID Value1 Value2 Value3 Value4 Value5 Value6
#1 1076 2940 1 A- 2 302 549
#2 1109 2940 <NA> A- 3 700 150
如果使用data.table
,则可以避免将所有列都转换为列表,而仅在需要的地方转换。
library(data.table)
setDT(df)
df[, lapply(.SD, function(x)
if(length(vals <- unique(x[!is.na(x)])) > 1)
list(vals)
else vals),
by = ID]
# ID Value1 Value2 Value3 Value4 Value5 Value6
# 1: 1076 2940 2,1 A- 2 302 549
# 2: 1109 2940 A- 3 700 150
如果您使用的是toString
,则可以删除if
并简化操作。 这也应适用于dplyr。
df[, lapply(.SD, function(x) toString(unique(x[!is.na(x)]))),
by = ID]
# 1: 1076 2940 2, 1 A- 2 302 549
# 2: 1109 2940 A- 3 700 150
修改后的示例数据(添加了具有> 1的不同值的案例)
df <- fread('
ID Value1 Value2 Value3 Value4 Value5 Value6
1076 2940 2 NA 2 NA NA
1076 2940 1 A- NA 302 549
1109 2940 NA NA 3 NA NA
1109 2940 NA A- NA 700 150
')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.