2015-03-20 2 views
4

в следующем фрейме. Я хочу держать строки только один раз, если они имеют повторяющиеся пары (1 4 и 4 1 считаются одной и той же парой) Var1 и Var2. Я думал о сортировке Var1 и Var2 в строке, а затем удалять повторяющиеся строки на основе как Var1, так и Var2. Однако я не добираюсь до желаемого результата.Удалите повторяющиеся пары столбцов, сортируйте строки на основе 2 столбцов

Это то, что выглядит мои данные, как:

Var1 <- c(1,2,3,4,5,5) 
Var2 <- c(4,3,2,1,5,5) 
f <- c("blue","green","yellow","red","orange2","grey") 
g <- c("blue","green","yellow","red","orange1","grey") 
testdata <- data.frame(Var1,Var2,f,g) 

можно сортировать в строках, однако значения столбцов е и г должны оставаться нетронутыми, как мне это сделать?

testdata <- t(apply(testdata, 1, function(x) x[order(x)])) 
testdata <- as.data.table(testdata) 

Затем я хочу, чтобы удалить повторяющиеся строки на основе Var1 и Var2

Я хочу, чтобы получить это в результате:

Var1 Var2 f  g 
1 4 blue blue 
2 3 green green 
5 5 orange2 orange1 

Спасибо за вашу помощь!

ответ

4

Вместо сортировки для всего набора данных, сортировки «var1», «var2», а затем использовать duplicated для удаления повторяющихся строк

testdata[1:2] <- t(apply(testdata[1:2], 1, sort)) 
testdata[!duplicated(testdata[1:2]),] 
# Var1 Var2  f  g 
#1 1 4 blue blue 
#2 2 3 green green 
#5 5 5 orange2 orange1 
3

Если данные являются большими, как в Sort large amout of data and save repeated pairs of values in R, используя apply() на каждой строке будет дорого. Вместо этого можно создать множество уникальных значений

uid = unique(unlist(testdata[c("Var1", "Var2")], use.names=FALSE)) 

определить, является ли своп необходимо

swap = match(testdata[["Var1"]], uid) > match(testdata[["Var2"]], uid) 

и обновления

tmp = testdata[swap, "Var1"] 
testdata[swap, "Var1"] = testdata[swap, "Var2"] 
testdata[swap, "Var2"] = tmp 

удалить дубликаты, как и прежде

testdata[!duplicated(testdata[1:2]),] 

Если было много дополнительные столбцы, и копирование их были дорогими, более самодостаточным решением было бы

uid = unique(unlist(testdata[c("Var1", "Var2")], use.names=FALSE)) 
swap = match(testdata[["Var1"]], uid) > match(testdata[["Var2"]], uid) 
idx = !duplicated(data.frame(
    V1 = ifelse(swap, testdata[["Var2"]], testdata[["Var1"]]), 
    V2 = ifelse(swap, testdata[["Var1"]], testdata[["Var2"]]))) 
testdata[idx, , drop=FALSE] 
4

В случае, если люди заинтересованы в решении этой помощи dplyr:

library(dplyr) 
testdata %>% 
    rowwise() %>% 
    mutate(key = paste(sort(c(Var1, Var2)), collapse="")) %>% 
    distinct(key, .keep_all=T) %>% 
    select(-key) 

# Source: local data frame [3 x 4] 
# Groups: <by row> 
# 
# # A tibble: 3 × 4 
# Var1 Var2  f  g 
# <dbl> <dbl> <fctr> <fctr> 
# 1  1  4 blue blue 
# 2  2  3 green green 
# 3  5  5 orange2 orange1 
Смежные вопросы