Набор данных фильтра Dplyr на основе значений, на которые ссылаются другие наборы данных, возвращает все строки или не возвращает ни одной

У меня возникла проблема с фильтрацией набора данных на основе значений, на которые ссылаются другие наборы данных.

У меня есть два набора данных. Первый набор данных, compare_dt, содержит все сравнения, которые я должен сделать, в виде строк с location1, location2. Второй набор данных, rain_values_dt, содержит значения, собранные из этих мест в разное время. Моя цель состоит в том, чтобы для каждой строки в compare_dt отфильтровать строки rain_values_dt, собранные из location1, отфильтровать строки rain_values_dt, собранные из location2, выполнить внутреннее соединение этих строк, запустить парный t-тест и вернуть статистику теста в добавленный столбец. для сравнения_dt.

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу фильтровать строки rain_values_dt на основе имени местоположения, на которое ссылается сравнение_dt. Запрос на фильтрацию на основе имени, хранящегося в первой строке таблицы сравнения, возвращает все строки rain_values_dt. Запрос на фильтрацию на основе имени, хранящегося в более высоких номерах строк, ничего не возвращает. Я хотел бы получать только строки с сайта, на который я ссылаюсь в фильтре.


library(data.table)
library(dplyr)

comparison_dt <- data.table(
  location1= c('austin_tx','austin_tx','austin_tx','boston_ma','boston_ma','boston_ma','chicago_il','chicago_il','chicago_il'),
  location2= c('austin_tx','boston_ma','chicago_il','austin_tx','boston_ma','chicago_il','austin_tx','boston_ma','chicago_il'),
  test_statistic= c()
)

rain_values_dt <- data.table(
  location=c('austin_tx','austin_tx','austin_tx','boston_ma','boston_ma','boston_ma','chicago_il','chicago_il','chicago_il'),
  month=c('march','april','may','march','april','may','march','april','may'),
  rainfall=c(1:9)
)

row_n=1

#my intended result, works as expected v
dplyr::filter(rain_values_dt, location == 'austin_tx')

#is pulling the correct name from the comparison table to filter on
comparison_dt[row_n,'location1']

#these are equivalent to each other, so I should be able to substitute, right?
'austin_tx' == comparison_dt[row_n,'location1']

#does not work, returns all values instead of filtering
dplyr::filter(rain_values_dt, location == comparison_dt[row_n,'location1'])

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

Раньше это работало, как ожидалось. Я перезапустил сеанс R, и он больше не работает должным образом.

Я попытался изменить имена местоположений в любом наборе данных на символьный или функциональный тип, основываясь на идее, что я мог импортировать свои наборы данных по-другому. Я попытался сослаться на столбец местоположения как вектор или в кавычках. Я попытался выгрузить и перезагрузить dplyr и проверить, использует ли R версию фильтра базовой статистики или версию dplyr. Это кажется простой проблемой, но я искал этот сайт и документацию filter() и не нашел ответа, почему функция может вести себя таким образом.


person Lewis    schedule 20.06.2021    source источник


Ответы (1)


Объект справа от == представляет собой data.table.

class(comparison_dt[row_n,'location1'])
[1] "data.table" "data.frame"

Нам нужно извлечь столбец как vector. Либо используйте $, либо [[

dplyr::filter(rain_values_dt, location == 
            comparison_dt[row_n,'location1']$location1)
     location month rainfall
1: austin_tx march        1
2: austin_tx april        2
3: austin_tx   may        3

или даже unlist для создания vector

dplyr::filter(rain_values_dt, location == 
            unlist(comparison_dt[row_n,'location1']))
    location month rainfall
1: austin_tx march        1
2: austin_tx april        2
3: austin_tx   may        3

Относительно того, почему мы получаем все строки набора данных: первым элементом «location1» является «austin_tx», который также является первым элементом «location» из «rank_values_dt». Таким образом, это TRUE из ==, который перерабатывается.

comparison_dt[row_n,'location1']
location1
1: austin_tx

Предположим, если значение столбца было 'boston_ma' в качестве первого элемента, оно вернет 0 строк, потому что поэлементное сравнение с первым сравнением элементов возвращает FALSE

dplyr::filter(rain_values_dt, location == data.table(location1 = 'boston_ma'))
Empty data.table (0 rows and 3 cols): location,month,rainfall
dplyr::filter(rain_values_dt, location == comparison_dt[row_n,'location1'])
     location month rainfall
1:  austin_tx march        1
2:  austin_tx april        2
3:  austin_tx   may        3
4:  boston_ma march        4
5:  boston_ma april        5
6:  boston_ma   may        6
7: chicago_il march        7
8: chicago_il april        8
9: chicago_il   may        9

т.е. если вынести выражение из filter, то становится понятнее - единственный выход ИСТИНА/ЛОЖЬ, который перерабатывается

rain_values_dt$location == data.table(location1 = 'boston_ma')
     location1
[1,]     FALSE
rain_values_dt$location == comparison_dt[row_n,'location1']
     location1
[1,]      TRUE

Для data.frame/data.table/tibble единицей является столбец. Таким образом, length из comparison_dt[, 'location1'] равно 1. Поэлементное поведение сравнения будет более выраженным, если мы добавим больше строк в 'comparison_dt'.

rain_values_dt$location == comparison_dt[3:5,'location1']
     location1
[1,]      TRUE
[2,]     FALSE
[3,]     FALSE

т. е. первый элемент ИСТИНА, потому что он сравнивает первый элемент «местоположения» из rain_values_dt с третьим элементом сравнения, но следующий элемент имеет значение ЛОЖЬ, потому что это «boston_ma» по сравнению со вторым элементом rain_values_dt$location, который снова равен « austin_tx'

person akrun    schedule 20.06.2021