2013-03-05 2 views
32

У меня есть два набора данных, которые должны быть одного размера, но не являются. Мне нужно обрезать значения из A, которые не находятся в B, и наоборот, чтобы исключить шум из графика, который входит в отчет. (Не волнуйтесь, эти данные не удалены навсегда!)Как я могу подмножать строки в кадре данных в R на основе вектора значений?

Я прочитал следующее:

Но я m все еще не в состоянии заставить это работать правильно. Вот мой код:

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 
+0

Вы попробовали 'merge'? – A5C1D2H2I1M1N2O1R2T1

+0

Я не думаю, что «слияние» здесь уместно. Мне не нужны комбинации данных. – Zelbinian

+8

Нет, я думаю, что «слияние» в точности соответствует. Внутреннее соединение дало бы вам только строки, которые находятся как в A, так и B. Затем вы можете подмножать столбцы результата, если слияние добавило какие-либо посторонние. – joran

ответ

49

Это даст вам то, что вы хотите:

eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg, ] 

Ошибка в вашей второй попытке, потому что вы забыли ,

В общем, для удобство, спецификация object[index] подмножества колонок для 2d object. Если вы хотите подмножать строки и сохранить все столбцы, вы должны использовать спецификацию object[index_rows, index_columns], а index_cols может быть пустым, и по умолчанию будут использоваться все столбцы.

Однако вам необходимо включить ,, чтобы указать, что вы хотите получить подмножество строк вместо поднабора столбцов.

+0

Да, это решает проблему. Я буду ждать других ответов, хотя на всякий случай кто-то придумает что-то действительно умное. :) – Zelbinian

+0

'subset' будет работать, если вы измените логический оператор на' subset (eg2011,! ID% in% bg2011missingFromBeg) ' –

+0

Это действительно тот же ответ, что и тот, который я написал. Выберите ответ adidender, так как он напрямую решает вашу проблему. Я добавил только мои, чтобы другие могли использовать их как более надежную ссылку, если они наткнутся на эту страницу позже. – Dinre

14

Если вы действительно просто хотите Подмножество каждый кадр данных по индексу, который существует в обоих кадрах данных, вы можете сделать это с помощью функции «матч», например, так:

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 
+0

Позвольте мне увидеть, могу ли я повторять 'data_A [data_A $ index% in% data_B $ index,]' словами. Дайте мне все строки в data_A, которые находятся как в data_A, так и в data_B, на основе их индекса. У меня все в порядке? – Zelbinian

+3

@Zelbinian В частности, он говорит: Дайте мне все строки в data_A, где значение индекса строк в data_A можно найти в значениях индекса в data_B. Это немного другое утверждение, но в принципе оно верно. Единственное отличие состоит в том, что мы специально хотим, чтобы номера строк из data_A.Если вы отмените это заявление, это не сработает правильно. – Dinre

+0

Хороший воспроизводимый пример + объяснения. –

1

за комментариями к исходному сообщению, м erges/join хорошо подходят для этой проблемы. В частности, внутреннее соединение вернет только значения, которые присутствуют в обоих кадрах данных, что делает ненужным заявление 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)) 

Чтобы сохранить данные в виде двух отдельных таблиц , каждый из которых содержит только свои собственные переменные, это подмножает ненужную таблицу только ее перед объединением. Затем в результирующую таблицу не добавляются новые переменные.

1

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

# 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 
Смежные вопросы