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

#r #dplyr #filtering

Вопрос:

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

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

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу фильтровать строки rain_values_dt на основе имени местоположения, на которое ссылается comparison_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. Это кажется простой проблемой, но я искал этот сайт и документацию по фильтру() и не нашел ответа на вопрос, почему функция может вести себя таким образом.

Ответ №1:

Объект в rhs == — это таблица данных.

 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 , оно станет более понятным — единственный вывод TRUE/FALSE, который перерабатывается

 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
 

т. е. первый элемент является ИСТИННЫМ, потому что он сравнивает первый элемент «location» из rain_values_dt с 3-м элементом сравнения, но следующий элемент является ЛОЖНЫМ, потому что это «boston_ma» по сравнению со 2-м элементом rain_values_dt$location, который снова является «austin_tx»