2015-05-06 17 views
9

Mam tabeli, która wygląda następująco:R: Dodaj kolumnę do tabeli z danymi z innej tabeli

Table1 <- data.frame(
    "Random" = c("A", "B", "C"), 
    "Genes" = c("Apple", "Candy", "Toothpaste"), 
    "Extra" = c("Up", "", "Down"), 
    "Desc" = c("Healthy,Red,Fruit", "Sweet,Cavities,Sugar,Fruity", "Minty,Dentist") 
) 

podając:

Random  Genes Extra      Desc 
1  A  Apple Up   Healthy,Red,Fruit 
2  B  Candy  Sweet,Cavities,Sugar,Fruity 
3  C Toothpaste Down    Minty,Dentist 

mam inną tabelę z opisem i chcesz dodać kolumny z genami. Na przykład Tabela 2 będzie:

Table2 <- data.frame(
    "Col1" = c(1, 2, 3, 4, 5, 6), 
    "Desc" = c("Sweet", "Sugar", "Dentist", "Red", "Fruit", "Fruity") 
) 

Dawanie:

Col1 Desc 
1 1 Sweet 
2 2 Sugar 
3 3 Dentist 
4 4  Red 
5 5 Fruit 
6 6 Fruity 

Chcę dodać kolejną kolumnę Table2 nazwie „Geny” odpowiadający „opis produktu” z obu tabel i dodaje genów z Table1 do otrzymujemy:

Col1 Desc Gene 
1 1 Sweet Candy 
2 2 Sugar Candy 
3 3 Dentist Toothpaste 
4 4  Red Apple 
5 5 Fruit Apple 
6 6 Fruity Candy 
+2

miałem pośmiać na wartość 'Toothpaste' dla' Gene'. –

Odpowiedz

8

można spróbować cSplit z splitstackshape podzielić opis produktu „” w kolumnie „Table1” i przekształcić zestaw danych z „szeroko” do formatu „długi”. Wynik będzie wynosił data.table. Możemy użyć metod data.table do ustawienia kolumny klucza jako "Desc" (setkey), połączyć z "Table2", a na końcu usunąć kolumny, które nie są potrzebne na wyjściu, poprzez wybranie kolumn lub przypisanie (:=) niechcianych kolumn NULL

library(splitstackshape) 
setkey(cSplit(Table1, 'Desc', ',', 'long'),Desc)[Table2[2:1]][ 
        ,c(5,4,2), with=FALSE] 
# Col1 Desc  Genes 
#1: 1 Sweet  Candy 
#2: 2 Sugar  Candy 
#3: 3 Dentist Toothpaste 
#4: 4  Red  Apple 
#5: 5 Fruit  Apple 
#6: 6 Fruity  Candy 
+0

@AlexA. Dzięki, będę aktualizować post – akrun

+0

Czy potrzebowałoby to również biblioteki (data.table)? Czy jest ładowany automatycznie przez bibliotekę (splitstackshape)? – TARehman

+0

@TARehman Jest ładowany automatycznie – akrun

5

Oto sposób podstawy R, który wykorzystuje związek pośredni tabelę łączącą:

# create an intermediate data.frame with all the key (Desc)/value (Gene) pairs 
df <- NULL 
for(i in seq(nrow(Table1))) 
    df <- rbind(df, 
        data.frame(Gene =Table1$Genes[i], 
          Desc =strsplit(as.character(Table1$Desc)[i],',')[[1]])) 
df 
#>   Gene  Desc 
#> 1  Apple Healthy 
#> 2  Apple  Red 
#> 3  Apple Fruit 
#> 4  Candy Sweet 
#> 5  Candy Cavities 
#> 6  Candy Sugar 
#> 7  Candy Fruity 
#> 8 Toothpaste Minty 
#> 9 Toothpaste Dentist 

teraz, aby go w zwykły sposób:

Table2$Gene <- df$Gene[match(Table2$Desc,df$Desc)] 
3

Zakładając, że każdy ciąg jest unikalny (tj. że Fruit nie może pojawić się w więcej niż jednym Gene), możesz to zrobić dość łatwo, używając pętli for i grep. Może to być powolne w przypadku ogromnego zbioru danych.

options(stringsAsFactors = FALSE) 
Table1 <- data.frame("Random" = c("A", "B", "C"), "Genes" = c("Apple", "Candy", "Toothpaste"), "Extra" = c("Up", "", "Down"), "Desc" = c("Healthy,Red,Fruit", "Sweet,Cavities,Sugar,Fruity", "Minty,Dentist")) 
Table2 <- data.frame("Col1" = c(1, 2, 3, 4, 5, 6), "Desc" = c("Sweet", "Sugar", "Dentist", "Red", "Fruit", "Fruity")) 

Table2$Gene <- NA 
for(x in 1:nrow(Table2)) { 

    Table2[x,"Gene"] <- Table1$Genes[grep(pattern = paste("\\b",Table2$Desc[x],"\\b",sep=""),x = Table1$Desc)] 
} 
Table2 

    Col1 Desc  Gene 
1 1 Sweet  Candy 
2 2 Sugar  Candy 
3 3 Dentist Toothpaste 
4 4  Red  Apple 
5 5 Fruit  Apple 
6 6 Fruity  Candy 
4

Jeśli możemy uzyskać klucz wyszukiwania w nazwie listy lub 2 wektorów (np 2 kolumna ramki danych) możemy skorzystać z funkcji int %l% on * qdapTools ** Pakiet I utrzymania. Najpierw podzielę twoje Table1$desc na listę nazwaną, używając funkcji strsplit. To jest klucz. Możemy wykonać wyszukiwanie przez Table2$Desc. Wykorzystuje dane *.Stół ** pakiet w backend, więc jest to dość szybki:

library(qdapTools) 

key <- setNames(strsplit(as.character(Table1[["Desc"]]), "\\s*,\\s*"), Table1[["Genes"]]) 

## $Apple 
## [1] "Healthy" "Red"  "Fruit" 
## 
## $Candy 
## [1] "Sweet" "Cavities" "Sugar" "Fruity" 
## 
## $Toothpaste 
## [1] "Minty" "Dentist" 

Table2[["Gene"]] <- Table2[["Desc"]] %l% key 

## Col1 Desc  Gene 
## 1 1 Sweet  Candy 
## 2 2 Sugar  Candy 
## 3 3 Dentist Toothpaste 
## 4 4  Red  Apple 
## 5 5 Fruit  Apple 
## 6 6 Fruity  Candy 

Oto czysta baza wektor odnośnika, który powinien być również bardzo szybki:

x <- strsplit(as.character(Table1[["Desc"]]), "\\s*,\\s*") 
key <- setNames(rep(Table1[["Genes"]], sapply(x, length)), unlist(x)) 
Table2[["Gene"]] <- key[match(Table2[["Desc"]], names(key))] 
3

Po @ odpowiedź TylerRinker za, ja sformatować Table1$Desc pierwszy ciąg:

Table1a  <- with(Table1, 
        stack(setNames(sapply(as.character(Desc),strsplit,split=","),Genes))) 
names(Table1a) <- c("Desc","Genes") 

Następnie przejdź do data.table:

require(data.table) 
DT1 <- data.table(Table1a,key="Desc") 
DT2 <- data.table(Table2,key="Desc") 

następnie scalić n-określić:

DT2[DT1,Gene:=Genes] 
# Col1 Desc  Gene 
# 1: 3 Dentist Toothpaste 
# 2: 5 Fruit  Apple 
# 3: 6 Fruity  Candy 
# 4: 4  Red  Apple 
# 5: 2 Sugar  Candy 
# 6: 1 Sweet  Candy 
+0

Dokładnie to robi '% l%' w ** qdapTools **. –

+0

@ TylerRinker Oh, dobrze wiedzieć. Fajna funkcja, która :) – Frank

Powiązane problemy