2016-01-28 2 views
0

У меня есть два кадра данных Test и User.Быстрая петля в r

Испытание имеет 100 000 рядов, в то время как Пользователь имеет 1 400 000 рядов. Я хочу извлечь определенные векторы из фрейма данных пользователя и объединить это с кадром тестовых данных. Например, я хочу, чтобы доход и кошка выполнялись для каждой строки в тесте от пользователя. Строки в тесте состоят из повторяющихся элементов, и я хочу получить любое значение из файла пользователя. Я хочу сохранить тестовый файл без удаления дубликатов.

Пример для Названия A Доход 100, Кошка М & L. Поскольку М происходят сначала мне нужно М.

> Test 
Name Income Cat  
A 
B 
C 
D 
... 

User Cat Income 
A M  100 
B M  320 
C U  400 
D L  900 
A L  100 
.. 

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

for (i in 1:nrow(Test) 
{ 
{ Test[i,"Cat"]<-User[which(User$Name==Test[i,"Name"]),"Cat"][1]} 
{ Test[i,"Income"]<-User[which(User$Name==Test[i,"Name"]),"Income"][1]}} 

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

Я хочу более быстрый способ сделать это, избегая цикла и слияния. Может ли кто-нибудь предложить какие-либо применения семейных функций.

+0

Функции 'apply' семейства являются оболочками для петель. Если вы не хотите зацикливаться, вы не должны запрашивать решения с помощью * apply. – RHertel

+0

Здравствуйте, Rhertel Спасибо за информацию, но как я могу использовать функции apply для решения вышеуказанной проблемы. – iamashish

ответ

1

Вы можете использовать match найти первую найденную строку (то векторизации копирование):

# Setup the data 
User=data.frame(User=c('A','B','C','D','A'),Cat=c('M','M','U','L','L'), 
       Income=c(100,320,400,900,100)) 
Test=data.frame(Name=c('A','B','C','D')) 
Test$Income<-NA 
Test$Cat<-NA 

> Test 
    Name Income Cat 
1 A  NA NA 
2 B  NA NA 
3 C  NA NA 
4 D  NA NA 


## Copy only the first match to from User to Test 
Test[,c("Income","Cat")]<-User[match(Test$Name,User$User),c("Income","Cat")] 

> Test 
    Name Income Cat 
1 A 100 M 
2 B 320 M 
3 C 400 U 
4 D 900 L 
+0

@fishtannk Спасибо за помощь. Но мне нужна помощь, когда я ставлю Match, как я могу убедиться, что я заберу меньший элемент, например, если у меня есть три года 2014,2015,2016 Я хочу выбрать 2014 год, но по умолчанию матч забирает последний год 2016 года. попробовал сортировку, но он делает тот же результат – iamashish

0

Используя dplyr пакет, который вы можете сделать что-то вроде этого:

library(dplyr) 
df %>% group_by(Name) %>% slice(1) 

Для примера, вы получите:

Оригинальный кадр данных:

df 
    Name Cat Income 
1 A M 100 
2 B M 320 
3 C U 400 
4 D L 900 
5 A L 100 

Комплектование первое вхождение:

df %>% group_by(Name) %>% slice(1) 
Source: local data frame [4 x 3] 
Groups: Name [4] 

    Name Cat Income 
    (chr) (chr) (int) 
1  A  M 100 
2  B  M 320 
3  C  U 400 
4  D  L 900 
Смежные вопросы