与整个数据集相比,计算每一行中唯一和不明确的元素
Count unique and ambiguous elements in each row compared to the whole dataset
我有一个包含数千行和将近一百列的数据集。每行仅包含唯一元素,但是,这些元素也可能在其他行中找到。
基本上,我想在我的数据框中创建两个新列,一个存储 Unique 的数量,另一个存储 Ambiguous[=28] 的数量=] 给定行中有元素,但 与整个数据集相比 。
请注意,数据框中有 NA,在计算唯一和不明确的元素时不应考虑这些元素。
df <- data.frame(
col1 = c('Ab', 'Cd', 'Ef', 'Gh', 'Ij'),
col2 = c('Ac', 'Ce', 'Eg', 'Gi', 'Ik'),
col3 = c('Acc', NA, 'Ab', 'Gef', 'Il'),
col4 = c(NA, NA, NA, 'Ce', 'Im')
)
在上面创建的数据框中,Ab 不是唯一的,因此与整个数据集相比,第 1 行中有 2 个唯一元素和 1 个不明确元素。
在我预期的输出中,第 1 行中的 Unique 等于 2,而 Ambiguous = 1。在第 5 行中,它分别为 4 和 0。
我已经搜索过可能的解决方案,但大多数解决方案只处理特定行中的唯一或重复元素,或特定列的多行。无论如何,我们将不胜感激。
这样的事情怎么样:
df <- data.frame(
col1 = c('Ab', 'Cd', 'Ef', 'Gh', 'Ij'),
col2 = c('Ac', 'Ce', 'Eg', 'Gi', 'Ik'),
col3 = c('Acc', NA, 'Ab', 'Gef', 'Il'),
col4 = c(NA, NA, NA, 'Ce', 'Im')
)
uvals <- avals <- rep(NA, nrow(df))
for(i in 1:nrow(df)){
other_vals <- na.omit(c(unique(as.matrix(df[-i,]))))
tmp <- na.omit(as.matrix(df)[i,]) %in% other_vals
uvals[i] <- sum(tmp == 0, na.rm=TRUE)
avals[i] <- sum(tmp == 1, na.rm=TRUE)
}
df <- df %>%
mutate(unique = uvals,
ambiguous = avals)
df
# col1 col2 col3 col4 unique ambiguous
# 1 Ab Ac Acc <NA> 2 1
# 2 Cd Ce <NA> <NA> 1 1
# 3 Ef Eg Ab <NA> 2 1
# 4 Gh Gi Gef Ce 3 1
# 5 Ij Ik Il Im 4 0
另一种避免重新计算的方法。
# First we get the duplicates to avoid recounting every time.
freqs <- table(as.matrix(df))
dupes <- names(freqs[freqs > 1])
# Check the values for (non-)duplication.
is_dupe <- rowSums(apply(df, 2, "%in%", dupes))
not_dupe <- rowSums(apply(df, 2, function(x) {!(x %in% dupes | is.na(x))}))
# Add the columns after we calculated the counts to avoid including them.
df$ambiguous <- is_dupe
df$unique <- not_dupe
df
# col1 col2 col3 col4 ambiguous unique
# 1 Ab Ac Acc <NA> 1 2
# 2 Cd Ce <NA> <NA> 1 1
# 3 Ef Eg Ab <NA> 1 2
# 4 Gh Gi Gef Ce 1 3
# 5 Ij Ik Il Im 0 4
我有一个包含数千行和将近一百列的数据集。每行仅包含唯一元素,但是,这些元素也可能在其他行中找到。
基本上,我想在我的数据框中创建两个新列,一个存储 Unique 的数量,另一个存储 Ambiguous[=28] 的数量=] 给定行中有元素,但 与整个数据集相比 。
请注意,数据框中有 NA,在计算唯一和不明确的元素时不应考虑这些元素。
df <- data.frame(
col1 = c('Ab', 'Cd', 'Ef', 'Gh', 'Ij'),
col2 = c('Ac', 'Ce', 'Eg', 'Gi', 'Ik'),
col3 = c('Acc', NA, 'Ab', 'Gef', 'Il'),
col4 = c(NA, NA, NA, 'Ce', 'Im')
)
在上面创建的数据框中,Ab 不是唯一的,因此与整个数据集相比,第 1 行中有 2 个唯一元素和 1 个不明确元素。
在我预期的输出中,第 1 行中的 Unique 等于 2,而 Ambiguous = 1。在第 5 行中,它分别为 4 和 0。
我已经搜索过可能的解决方案,但大多数解决方案只处理特定行中的唯一或重复元素,或特定列的多行。无论如何,我们将不胜感激。
这样的事情怎么样:
df <- data.frame(
col1 = c('Ab', 'Cd', 'Ef', 'Gh', 'Ij'),
col2 = c('Ac', 'Ce', 'Eg', 'Gi', 'Ik'),
col3 = c('Acc', NA, 'Ab', 'Gef', 'Il'),
col4 = c(NA, NA, NA, 'Ce', 'Im')
)
uvals <- avals <- rep(NA, nrow(df))
for(i in 1:nrow(df)){
other_vals <- na.omit(c(unique(as.matrix(df[-i,]))))
tmp <- na.omit(as.matrix(df)[i,]) %in% other_vals
uvals[i] <- sum(tmp == 0, na.rm=TRUE)
avals[i] <- sum(tmp == 1, na.rm=TRUE)
}
df <- df %>%
mutate(unique = uvals,
ambiguous = avals)
df
# col1 col2 col3 col4 unique ambiguous
# 1 Ab Ac Acc <NA> 2 1
# 2 Cd Ce <NA> <NA> 1 1
# 3 Ef Eg Ab <NA> 2 1
# 4 Gh Gi Gef Ce 3 1
# 5 Ij Ik Il Im 4 0
另一种避免重新计算的方法。
# First we get the duplicates to avoid recounting every time.
freqs <- table(as.matrix(df))
dupes <- names(freqs[freqs > 1])
# Check the values for (non-)duplication.
is_dupe <- rowSums(apply(df, 2, "%in%", dupes))
not_dupe <- rowSums(apply(df, 2, function(x) {!(x %in% dupes | is.na(x))}))
# Add the columns after we calculated the counts to avoid including them.
df$ambiguous <- is_dupe
df$unique <- not_dupe
df
# col1 col2 col3 col4 ambiguous unique
# 1 Ab Ac Acc <NA> 1 2
# 2 Cd Ce <NA> <NA> 1 1
# 3 Ef Eg Ab <NA> 1 2
# 4 Gh Gi Gef Ce 1 3
# 5 Ij Ik Il Im 0 4