R:合并重复的观察结果?
R: Consolidating duplicate observations?
我有一个大型数据框,其中包含大约 500,000 个观察值(由 "ID" 标识)和 150 多个变量。有些观察只出现一次;其他人出现多次(超过 10 次左右)。我想 "collapse" 这些多个观察结果,以便每个唯一 ID 只有一行,并且 2:150 列中的所有信息都被连接起来。我不需要对这些观察结果进行任何计算 运行,只需快速修改即可。
我试过:
df.new <- group_by(df,"ID")
还有:
library(data.table)
dt = data.table(df)
dt.new <- dt[, lapply(.SD, na.omit), by = "ID"]
不幸的是,两者都没有用。感谢您的帮助!
怎么样?
df %>%
group_by(ID) %>%
summarise_each(funs(paste0(., collapse = "/")))
或reproducible...
iris %>%
group_by(Species) %>%
summarise_each(funs(paste0(., collapse = "/")))
我过去也遇到过类似的问题,但我没有处理相同数据的多个副本。在许多情况下只有 2 个实例,在某些情况下有 3 个实例。以下是我的方法。希望对您有所帮助。
idx <- duplicated(df$key) | duplicated(df$key, fromLast=TRUE) # get the index of the duplicate entries. Or will help get the original value too.
dupes <- df[idx,] # get duplicated values
non_dupes <- df[!idx,] # get all non duplicated values
temp <- dupes %>% group_by(key) %>% # roll up the duplicated ones.
fill_(colnames(dupes), .direction = "down") %>%
fill_(colnames(dupes), .direction = "up") %>%
slice(1)
然后很容易合并回temp
和non_dupes
。
编辑
我强烈建议将 df
过滤到尽可能多且与您的最终目标相关的人群,因为此过程可能需要一些时间。
使用基本 R:
df = data.frame(ID = c("a","a","b","b","b","c","d","d"),
day = c("1","2","3","4","5","6","7","8"),
year = c(2016,2017,2017,2016,2017,2016,2017,2016),
stringsAsFactors = F)
> df
ID day year
1 a 1 2016
2 a 2 2017
3 b 3 2017
4 b 4 2016
5 b 5 2017
6 c 6 2016
7 d 7 2017
8 d 8 2016
做:
z = aggregate(df[,2:3],
by = list(id = df$ID),
function(x){ paste0(x, collapse = "/") }
)
结果:
> z
id day year
1 a 1/2 2016/2017
2 b 3/4/5 2017/2016/2017
3 c 6 2016
4 d 7/8 2017/2016
编辑
如果你想避免 "collapsing" NA 做:
z = aggregate(df[,2:3],
by = list(id = df$ID),
function(x){ paste0(x[!is.na(x)],collapse = "/") })
对于这样的数据框:
> df
ID day year
1 a 1 2016
2 a 2 NA
3 b 3 2017
4 b 4 2016
5 b <NA> 2017
6 c 6 2016
7 d 7 2017
8 d 8 2016
结果是:
> z
id day year
1 a 1/2 2016
2 b 3/4 2017/2016/2017
3 c 6 2016
4 d 7/8 2017/2016
我有一个大型数据框,其中包含大约 500,000 个观察值(由 "ID" 标识)和 150 多个变量。有些观察只出现一次;其他人出现多次(超过 10 次左右)。我想 "collapse" 这些多个观察结果,以便每个唯一 ID 只有一行,并且 2:150 列中的所有信息都被连接起来。我不需要对这些观察结果进行任何计算 运行,只需快速修改即可。
我试过:
df.new <- group_by(df,"ID")
还有:
library(data.table)
dt = data.table(df)
dt.new <- dt[, lapply(.SD, na.omit), by = "ID"]
不幸的是,两者都没有用。感谢您的帮助!
怎么样?
df %>%
group_by(ID) %>%
summarise_each(funs(paste0(., collapse = "/")))
或reproducible...
iris %>%
group_by(Species) %>%
summarise_each(funs(paste0(., collapse = "/")))
我过去也遇到过类似的问题,但我没有处理相同数据的多个副本。在许多情况下只有 2 个实例,在某些情况下有 3 个实例。以下是我的方法。希望对您有所帮助。
idx <- duplicated(df$key) | duplicated(df$key, fromLast=TRUE) # get the index of the duplicate entries. Or will help get the original value too.
dupes <- df[idx,] # get duplicated values
non_dupes <- df[!idx,] # get all non duplicated values
temp <- dupes %>% group_by(key) %>% # roll up the duplicated ones.
fill_(colnames(dupes), .direction = "down") %>%
fill_(colnames(dupes), .direction = "up") %>%
slice(1)
然后很容易合并回temp
和non_dupes
。
编辑
我强烈建议将 df
过滤到尽可能多且与您的最终目标相关的人群,因为此过程可能需要一些时间。
使用基本 R:
df = data.frame(ID = c("a","a","b","b","b","c","d","d"),
day = c("1","2","3","4","5","6","7","8"),
year = c(2016,2017,2017,2016,2017,2016,2017,2016),
stringsAsFactors = F)
> df
ID day year
1 a 1 2016
2 a 2 2017
3 b 3 2017
4 b 4 2016
5 b 5 2017
6 c 6 2016
7 d 7 2017
8 d 8 2016
做:
z = aggregate(df[,2:3],
by = list(id = df$ID),
function(x){ paste0(x, collapse = "/") }
)
结果:
> z
id day year
1 a 1/2 2016/2017
2 b 3/4/5 2017/2016/2017
3 c 6 2016
4 d 7/8 2017/2016
编辑
如果你想避免 "collapsing" NA 做:
z = aggregate(df[,2:3],
by = list(id = df$ID),
function(x){ paste0(x[!is.na(x)],collapse = "/") })
对于这样的数据框:
> df
ID day year
1 a 1 2016
2 a 2 NA
3 b 3 2017
4 b 4 2016
5 b <NA> 2017
6 c 6 2016
7 d 7 2017
8 d 8 2016
结果是:
> z
id day year
1 a 1/2 2016
2 b 3/4 2017/2016/2017
3 c 6 2016
4 d 7/8 2017/2016