2015-05-06 13 views
9

Tôi có một bảng trông như sau:R: Thêm cột vào bảng với dữ liệu từ bảng khác

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") 
) 

cho:

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

Tôi có một bảng với mô tả và muốn thêm một cột có gen. Ví dụ Table2 sẽ là:

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

Giving:

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

Tôi muốn thêm một cột để Table2 có tên là "gen" phù hợp với "quyết định" từ hai bảng và thêm các gen từ Table1 để nhận được:

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

Tôi đã có một tiếng cười tốt theo giá trị của 'Toothpaste' cho' Gene'. –

Trả lời

8

Bạn có thể thử cSplit từ splitstackshape để phân chia các cột 'quyết định' trong "Table1" và chuyển đổi dữ liệu từ 'rộng' sang định dạng 'dài'. Đầu ra sẽ là data.table. Chúng ta có thể sử dụng phương thức data.table để thiết lập cột khóa là 'Desc' (setkey), tham gia với "Table2", và cuối cùng loại bỏ các cột không cần thiết trong đầu ra bằng cách chọn cột hoặc gán (:=) để 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. Cảm ơn, tôi sẽ cập nhật các bài viết – akrun

+0

Điều này cũng cần thư viện (data.table)? Hoặc là nó được tải tự động bởi thư viện (splitstackshape)? – TARehman

+0

@TARehman Nó được tải tự động – akrun

5

đây là một phương pháp trong cơ sở R có sử dụng một bảng liên kết trung gian:

# 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 

Bây giờ liên kết với nó theo cách thông thường:

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

Giả sử rằng mỗi chuỗi là duy nhất (tức là rằng trái cây không thể xuất hiện cho nhiều hơn một gen), bạn có thể làm điều này khá dễ dàng bằng cách sử dụng một vòng lặp forgrep. Nó có thể chậm trên một tập dữ liệu khổng lồ tuy nhiên.

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

Nếu chúng ta có thể nhận được một tra cứu chìa khóa vào một danh sách tên hoặc 2 vectơ (ví dụ, 2 cột khung dữ liệu), chúng tôi có thể sử dụng chức năng %l% int ông * qdapTools ** gói tôi duy trì. Trước tiên, tôi sẽ chia Table1$desc của bạn thành một danh sách có tên bằng cách sử dụng chức năng strsplit. Đó là chìa khóa. Chúng tôi có thể thực hiện tra cứu qua Table2$Desc. Điều này sử dụng dữ liệu *.bảng ** gói trong backend vì vậy nó khá nhanh chóng:

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 

Dưới đây là một tra cứu vector cơ sở tinh khiết mà cũng nên được khá nhanh chóng:

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

Sau @ câu trả lời TylerRinker, tôi muốn định dạng Table1$Desc chuỗi đầu tiên:

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

Sau đó đi đến data.table:

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

Sau đó merge-n-xác định:

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

Đây chính xác là những gì '% l%' trong ** qdapTools ** đang thực hiện. –

+0

@TylerRinker Ồ, rất vui được biết. Cool chức năng, mà :) – Frank

Các vấn đề liên quan