Как я могу подмножать строки в кадре данных в R на основе вектора значений?
У меня есть два набора данных, которые должны быть одного размера, но не являются. Мне нужно обрезать значения из A, которые не находятся в B, и наоборот, чтобы исключить шум из графика, который входит в отчет. (Не беспокойтесь, эти данные не удаляются навсегда!)
Я прочитал следующее:
Но я все еще не могу заставить это работать правильно. Здесь мой код:
bg2011missingFromBeg <- setdiff(x=eg2011$ID, y=bg2011$ID)
#attempt 1
eg2011cleaned <- subset(eg2011, ID != bg2011missingFromBeg)
#attempt 2
eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg]
Первая попытка просто исключает первое значение в результирующем векторе setdiff. Вторая попытка дает и громоздкую ошибку:
Error in `[.data.frame`(eg2012, !eg2012$ID %in% bg2012missingFromBeg)
: undefined columns selected
Ответы
Ответ 1
Это даст вам то, что вы хотите:
eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg, ]
Ошибка во второй попытке состоит в том, что вы забыли ,
В общем, для удобства спецификация object[index]
подмножает столбцы для 2d object
. Если вы хотите подмножить строки и сохранить все столбцы, вы должны использовать спецификацию
object[index_rows, index_columns]
, а index_cols
может быть пустым, и по умолчанию будут использоваться все столбцы.
Однако вам все равно нужно включить ,
, чтобы указать, что вы хотите получить подмножество строк вместо поднабора столбцов.
Ответ 2
Если вы действительно хотите подмножить каждый кадр данных индексом, который существует в обоих кадрах данных, вы можете сделать это с помощью функции "match", например:
data_A[match(data_B$index, data_A$index, nomatch=0),]
data_B[match(data_A$index, data_B$index, nomatch=0),]
Это, тем не менее, то же самое, что:
data_A[data_A$index %in% data_B$index,]
data_B[data_B$index %in% data_A$index,]
Вот демо:
# Set seed for reproducibility.
set.seed(1)
# Create two sample data sets.
data_A <- data.frame(index=sample(1:200, 90, rep=FALSE), value=runif(90))
data_B <- data.frame(index=sample(1:200, 120, rep=FALSE), value=runif(120))
# Subset data of each data frame by the index in the other.
t_A <- data_A[match(data_B$index, data_A$index, nomatch=0),]
t_B <- data_B[match(data_A$index, data_B$index, nomatch=0),]
# Make sure they match.
data.frame(t_A[order(t_A$index),], t_B[order(t_B$index),])[1:20,]
# index value index.1 value.1
# 27 3 0.7155661 3 0.65887761
# 10 12 0.6049333 12 0.14362694
# 88 14 0.7410786 14 0.42021589
# 56 15 0.4525708 15 0.78101754
# 38 18 0.2075451 18 0.70277874
# 24 23 0.4314737 23 0.78218212
# 34 32 0.1734423 32 0.85508236
# 22 38 0.7317925 38 0.56426384
# 84 39 0.3913593 39 0.09485786
# 5 40 0.7789147 40 0.31248966
# 74 43 0.7799849 43 0.10910096
# 71 45 0.2847905 45 0.26787813
# 57 46 0.1751268 46 0.17719454
# 25 48 0.1482116 48 0.99607737
# 81 53 0.6304141 53 0.26721208
# 60 58 0.8645449 58 0.96920881
# 30 59 0.6401010 59 0.67371223
# 75 61 0.8806190 61 0.69882454
# 63 64 0.3287773 64 0.36918946
# 19 70 0.9240745 70 0.11350771
Ответ 3
В комментариях к исходному сообщению слияния/объединения хорошо подходят для этой проблемы. В частности, внутреннее соединение вернет только значения, которые присутствуют в обоих кадрах данных, что делает оператор setdiff
ненужным.
Используя данные из примера Dinre:
В базе R:
cleanedA <- merge(data_A, data_B[, "index"], by = 1, sort = FALSE)
cleanedB <- merge(data_B, data_A[, "index"], by = 1, sort = FALSE)
Использование пакета dplyr:
library(dplyr)
cleanedA <- inner_join(data_A, data_B %>% select(index))
cleanedB <- inner_join(data_B, data_A %>% select(index))
Чтобы сохранить данные в виде двух отдельных таблиц, каждая из которых содержит только свои собственные переменные, это подмножает ненужную таблицу только ее индексной переменной перед присоединением. Затем в результирующую таблицу не добавляются новые переменные.
Ответ 4
Действительно человеческий понятный пример (поскольку это первый раз, когда я использую% in%), как сравнивать два кадра данных и хранить только строки, содержащие равные значения в определенном столбце:
# Set seed for reproducibility.
set.seed(1)
# Create two sample data frames.
data_A <- data.frame(id=c(1,2,3), value=c(1,2,3))
data_B <- data.frame(id=c(1,2,3,4), value=c(5,6,7,8))
# compare data frames by specific columns and keep only
# the rows with equal values
data_A[data_A$id %in% data_B$id,] # will keep data in data_A
data_B[data_B$id %in% data_A$id,] # will keep data in data_b
Результаты:
> data_A[data_A$id %in% data_B$id,]
id value
1 1 1
2 2 2
3 3 3
> data_B[data_B$id %in% data_A$id,]
id value
1 1 5
2 2 6
3 3 7