基于限制的数据框中多列的频率列表

Frequency list from multiple columns in dataframe based on restriction

我有一个包含单词(w1、w2 等列)及其持续时间的 df,其中一些是 NA(d1、d2 等列),就像这个:

set.seed(47)
df <- data.frame(
  w1 = c(sample(LETTERS[1:4], 10, replace = T)),
  w2 = c(sample(LETTERS[1:4], 10, replace = T)),
  w3 = c(sample(LETTERS[1:4], 10, replace = T)),
  w4 = c(sample(LETTERS[1:4], 10, replace = T)),
  d1 = c(rep(NA, 3), round(rnorm(7),3)),
  d2 = c(round(rnorm(6),3), NA, round(rnorm(3),3)),
  d3 = c(round(rnorm(2),3), rep(NA,2), round(rnorm(6),3)),
  d4 = c(round(rnorm(1),3), NA, round(rnorm(8),3))
)
   w1 w2 w3 w4     d1     d2     d3     d4
1   D  A  A  C     NA -2.322 -0.693 -0.488
2   B  C  C  B     NA -1.967  0.261     NA
3   D  A  C  B     NA  0.028     NA  -0.92
4   D  C  A  A -1.566  0.484     NA  0.898
5   C  C  C  D  0.249  0.144  0.507 -0.356
6   C  D  B  B  -0.34   -1.2  0.564  1.032
7   B  B  A  A  0.417     NA  0.061  0.664
8   B  A  A  D -0.326  0.885 -0.109   0.97
9   C  A  C  B  -0.89  0.887 -0.155  1.676
10  D  B  D  C -1.608  0.001   0.95  1.988

我想要得到的是在相应持续时间内 not 不适用的所有单词 tokens 的单频列表柱子。因此,例如,w1 列中的 "D" 在 d1 中为 NA,因此此标记不应包含在频率计数中。 这是如何在 base R 中编程的,最好是在一行代码中?

忽略相应列中 NA 的值:

table(unlist(replace(df[paste0("w", 1:4)], is.na(df[paste0("d", 1:4)]), NA)))
#  B  C  D  A 
#  7 11  6  9 
# Alternate approach
table(unlist(df[1:4])[!is.na(unlist(df[5:8]))])
#  B  C  D  A 
#  7 11  6  9 

完全省略任何地方有 NA 的值:

它是 3 行,但我会这样做:

all_words = unlist(df[1:4])
na_words = all_words[is.na(unlist(df[5:8]))]
table(droplevels(all_words[! all_words %in% na_words]))
# < table of extent 0 >

你可以在一行中完成,但它更丑陋,很难说出发生了什么。

table(droplevels(unlist(df[1:4])[! unlist(df[1:4]) %in% unlist(df[1:4])[is.na(unlist(df[5:8]))]]))

对于给定的示例数据,它给出长度为 0 的 table,因为所有唯一单词在某处都有一个 NA。如果您更改输入数据以使用更多字母,我们将得到非空结果:

set.seed(47)
df2 <- data.frame(
  w1 = c(sample(LETTERS[1:8], 10, replace = T)),
  w2 = c(sample(LETTERS[1:8], 10, replace = T)),
  w3 = c(sample(LETTERS[1:8], 10, replace = T)),
  w4 = c(sample(LETTERS[1:8], 10, replace = T)),
  d1 = c(rep(NA, 3), round(rnorm(7),3)),
  d2 = c(round(rnorm(6),3), NA, round(rnorm(3),3)),
  d3 = c(round(rnorm(2),3), rep(NA,2), round(rnorm(6),3)),
  d4 = c(round(rnorm(1),3), NA, round(rnorm(8),3))
)
table(droplevels(unlist(df2[1:4])[! unlist(df2[1:4]) %in% unlist(df2[1:4])[is.na(unlist(df2[5:8]))]]))
# F A 
# 5 4