这个问题是建立在另一个问题上的 在一个数据框架中,通过ID和不同的列类型,R组合重复的行。. 我有一个数据表,里面有一列 time
和其他一些不同类型的列(系数和数字)。下面是一个例子。
dt <- data.table(time = c(1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4),
abst = c(0, NA, 2, NA, NA, NA, 0, 0, NA, 2, NA, 3, 4),
farbe = as.factor(c("keine", NA, "keine", NA, NA, NA, "keine", "keine", NA, NA, NA, "rot", "blau")),
gier = c(0, NA, 5, NA, NA, NA, 0, 0, NA, 1, NA, 6, 2),
goff = as.factor(c("haus", "maus", "toll", NA, "haus", NA, "maus", NA, NA, NA, NA, NA, "maus")),
huft = as.factor(c(NA, NA, NA, NA, NA, "wolle", NA, NA, "wolle", NA, NA, "holz", NA)),
mode = c(4, 2, NA, NA, 6, 5, 0, NA, NA, NA, NA, NA, 3))
现在我想把列中的重复次数合并起来 time
. 数字列被定义为所有相同ID的平均值(不含NAs!)。因子列合并为一个。NAs可以省略。
dtRes <- data.table(time = c(1, 1, 1, 2, 3, 4, 4),
abst = c(1, 1, 1, 0, 0, 3, 3),
farbe = as.factor(c("keine", "keine", "keine", "keine", "keine", "rot", "blau")),
gier = c(2.5, 2.5, 2.5, 0, 0, 3, 3),
goff = as.factor(c("haus", "maus", "toll", "maus", NA, "maus", "maus")),
huft = as.factor(c(NA, NA, NA, "wolle", "wolle", "holz", "holz")),
mode = c(4, 4, 4, 2.5, NA, 3, 3))
我需要一些快速的计算,因为我有大约一百万个观测值。
对于这个问题,我有一些额外的想法。farbe
可能不是唯一的 在这种情况下,我认为对我的数据最好的想法是有一个重复的行,但只有不同的 farbe
所以有2个相同的时间,其余的时间都保持不变,但不同的值是指 farbe
. 这应该只是非常罕见的情况下,但将是一个伟大的补充。
另外,在我的真实数据中,我有更多的数字列和因子列,所以我不想单独定义每一列。我的真实数据中有更多的数字和因子列 所以我不想单独定义每一列。在一些数据表中,是没有因子列的。所以,即使没有数值(time
是一直存在的,而且是数字)或因数列。
先谢谢你
预期的结果(对于给定的样本数据集)也可以实现。橆 随后呼叫 separate_rows()
或 cSplit()
:
library(data.table) # version 1.12.9
dt[, lapply(.SD, function(x) if (is.numeric(x)) mean(x, na.rm = TRUE)
else unlist(na.omit(unique(x)))), by = time]
time abst farbe gier goff huft mode
1: 1 1 keine 2.5 haus <NA> 4.0
2: 1 1 keine 2.5 maus <NA> 4.0
3: 1 1 keine 2.5 toll <NA> 4.0
4: 2 0 keine 0.0 maus wolle 2.5
5: 3 0 keine 0.0 <NA> wolle NaN
6: 4 3 rot 3.0 maus holz 3.0
7: 4 3 blau 3.0 maus holz 3.0
请注意,这种方法适用于数值列和因子列的任意组合。没有 列名需要明确说明。
然而,我确实 相信 对基本问题的正确答案是返回 每行 time
而不是一种部分合计(当然,您的里程数可能会有所不同)。
dt[, lapply(.SD, function(x) if (is.numeric(x)) mean(x, na.rm = TRUE)
else list(na.omit(unique(x)))), by = time]
time abst farbe gier goff huft mode 1: 1 1 keine 2.5 haus,maus,toll 4.0 2: 2 0 keine 0.0 maus wolle 2.5 3: 3 0 keine 0.0 wolle NaN 4: 4 3 rot,blau 3.0 maus holz 3.0
请注意 list()
而不是 toString()
已被用于汇总因子列。这样做的好处是避免在其中一个因子级数包含逗号的情况下出现问题。,
偶然。此外,更容易识别出具有非独特因素的案例,每 time
在一个大的生产数据集中。
# compute aggregate as before
dtRes <- dt[, lapply(.SD, function(x) if (is.numeric(x)) mean(x, na.rm = TRUE)
else list(na.omit(unique(x)))), by = time]
# find cases with non-unique factors per group
# note .SDcols = is.list is available with data.table version 1.12.9
tmp <- dtRes[, which(Reduce(sum, lapply(.SD, function(x) lengths(x) > 1L)) > 0), .SDcols = is.list, by = time]
tmp
time V1 1: 1 1 2: 4 1
# show affected rows
dtRes[tmp, on = "time"]
time abst farbe gier goff huft mode V1 1: 1 1 keine 2.5 haus,maus,toll 4 1 2: 4 3 rot,blau 3.0 maus holz 3 1
# show not affected rows
dtRes[!tmp, on = "time"]
time abst farbe gier goff huft mode 1: 2 0 keine 0 maus wolle 2.5 2: 3 0 keine 0 wolle NaN
我们可以做一个组由 mean
library(data.table)
library(tidyr)
library(dplyr)
dt[, lapply(.SD, function(x) if(is.numeric(x)) mean(x, na.rm = TRUE)
else toString(unique(x[!is.na(x)]))), .(time)] %>%
separate_rows(farbe, goff)
# A tibble: 7 x 7
# time abst farbe gier goff huft mode
# <dbl> <dbl> <chr> <dbl> <chr> <chr> <dbl>
#1 1 1 keine 2.5 "haus" "" 4
#2 1 1 keine 2.5 "maus" "" 4
#3 1 1 keine 2.5 "toll" "" 4
#4 2 0 keine 0 "maus" "wolle" 2.5
#5 3 0 keine 0 "" "wolle" NaN
#6 4 3 rot 3 "maus" "holz" 3
#7 4 3 blau 3 "maus" "holz" 3
或与 cSplit
library(splitstackshape)
cSplit(dt[, lapply(.SD, function(x) if(is.numeric(x))
mean(x, na.rm = TRUE) else toString(unique(x[!is.na(x)]))), .(time)],
c('farbe', 'goff'), sep= ',\\s*', 'long', fixed = FALSE)
# time abst farbe gier goff huft mode
#1: 1 1 keine 2.5 haus 4.0
#2: 1 1 <NA> 2.5 maus 4.0
#3: 1 1 <NA> 2.5 toll 4.0
#4: 2 0 keine 0.0 maus wolle 2.5
#5: 3 0 keine 0.0 <NA> wolle NaN
#6: 4 3 rot 3.0 maus holz 3.0
#7: 4 3 blau 3.0 <NA> holz 3.0