Соответствие между наборами данных и столбцами - PullRequest
1 голос
/ 23 октября 2019

У меня есть вектор со словами, например, вот так:

 w <- LETTERS[1:5]

и фрейм данных с токенами этих слов, но также токены других слов в разных столбцах, например, вот так:

set.seed(21)
df <- data.frame(
  w1 = c(sample(LETTERS, 10)),
  w2 = c(sample(LETTERS, 10)),
  w3 = c(sample(LETTERS, 10)),
  w4 = c(sample(LETTERS, 10))
)
df
   w1 w2 w3 w4
1   U  R  A  Y
2   G  X  P  M
3   Q  B  S  R
4   E  O  V  T
5   V  D  G  W
6   T  A  Q  E
7   C  K  L  U
8   D  F  O  Z
9   R  I  M  G
10  O  T  T  I
# convert factor to character:
df[] <- lapply(df[], as.character)

Я бы хотел извлечь из df всех токенов тех слов, которые содержатся в векторе w. Я могу сделать это так, но это выглядит не очень хорошо, и очень многократно и подвержено ошибкам, если размер кадра данных больше:

extract <- c(df$w1[df$w1 %in% w],
             df$w2[df$w2 %in% w], 
             df$w3[df$w3 %in% w], 
             df$w4[df$w4 %in% w])

Я пробовал это, используя paste0, чтобы избежать обращения к каждому столбцу отдельно, ноэто не работает:

extract <- df[paste0("w", 1:4)][df[paste0("w", 1:4)] %in% w]
extract
data frame with 0 columns and 10 rows

Что не так с этим кодом? Или какой другой код будет работать?

1 Ответ

1 голос
/ 23 октября 2019

Чтобы ответить на ваш вопрос «Что не так с этим кодом?»: Код df[paste0("w", 1:4)][df[paste0("w", 1:4)] %in% w] эквивалентен df[df %in% w], потому что df[paste0("w", 1:4)], который вы используете дважды, просто возвращает всю сумму df. Это означает, что df %in% w вернет FALSE FALSE FALSE FALSE, поскольку ни одна из переменных в df не находится в w (w содержит строки, но не векторы строк), а df[c(F, F, F, F)] возвращает пустой фрейм данных.

Если вы имеете дело с одним типом данных (строками), и выходные данные могут быть символьным вектором, тогда используйте матрицу вместо фрейма данных, который быстрее и в этом случае немного легчеподмножество:

mat <- as.matrix(df)
mat[mat %in% w]

#[1] "B" "D" "E" "E" "A" "B" "E" "B"

Это выдает тот же результат, что и ваша попытка выше с extract <- ….

Если вы хотите сохранить некоторое подобие исходной структуры фрейма данных, вы можете попробовать следующее, который выводит список (необходимо, поскольку возвращаемые векторы для каждой переменной могут иметь различную длину):

lapply(df, function(x) x[x %in% w])

#### OUTPUT ####
$w1
[1] "B" "D" "E"

$w2
[1] "E" "A"

$w3
[1] "B"

$w4
[1] "E" "B"

Просто вызовите unlist или unclass в возвращенном списке, если вы хотите вектор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...