2017-10-20 76 views
2

我有一個數據幀作爲多的行,兩列的範圍如下:擴展的數據幀具有在原始行

structure(list(symbol = c("u", "n", "v", "i", "a"), start = c(9L, 
6L, 10L, 8L, 7L), end = c(14L, 15L, 12L, 13L, 11L)), .Names = c("symbol", 
"start", "end"), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5")) 

我希望儘可能多的行,也有在的範圍內的值(開始,結束)每個符號。所以,最後的數據幀的樣子:

structure(list(symbol = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 4L, 5L, 5L, 5L, 5L, 5L), .Label = c("a", "l", "n", "v", "y" 
), class = "factor"), value = c(7L, 8L, 9L, 10L, 11L, 6L, 7L, 
8L, 9L, 10L, 11L, 12L, 13L, 14L, 8L, 9L, 10L, 11L, 12L, 10L, 
11L, 12L, 13L, 14L, 15L, 9L, 10L, 11L, 12L, 13L)), class = "data.frame", row.names = c(NA, 
-30L), .Names = c("symbol", "value")) 

我想我可以簡單地每行值的列表,然後使用tidyr包的unnest如下:

df$value <- apply(df, 1, function(x) as.list(x[2]:x[3])) 
dput(df) 
structure(list(symbol = structure(c(4L, 3L, 5L, 2L, 1L), .Label = c("a", 
"i", "n", "u", "v"), class = "factor"), start = c(9L, 6L, 10L, 
8L, 7L), end = c(14L, 15L, 12L, 13L, 11L), value = structure(list(
    `1` = list(9L, 10L, 11L, 12L, 13L, 14L), `2` = list(6L, 7L, 
     8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L), `3` = list(10L, 
     11L, 12L), `4` = list(8L, 9L, 10L, 11L, 12L, 13L), `5` = list(
     7L, 8L, 9L, 10L, 11L)), .Names = c("1", "2", "3", "4", 
"5"))), .Names = c("symbol", "start", "end", "value"), row.names = c("1", 
"2", "3", "4", "5"), class = "data.frame") 

df 
    symbol start end        value 
1  u  9 14    9, 10, 11, 12, 13, 14 
2  n  6 15 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 
3  v 10 12       10, 11, 12 
4  i  8 13    8, 9, 10, 11, 12, 13 
5  a  7 11     7, 8, 9, 10, 11 

然後做:

library(tidyr) 
unnest(df, value) 

不過,我覺得我打這個懸而未決的特性/錯誤: https://github.com/tidyverse/tidyr/issues/278

Error: Each column must either be a list of vectors or a list of data frames [value] 

有沒有更好的方法來做到這一點,特別是避免申請家庭?

回答

2

賦值給每個一行dplyr,我們可以使用rowwisedo

library(dplyr) 
df1 %>% 
    rowwise() %>% 
    do(data.frame(symbol= .$symbol, value = .$start:.$end)) %>% 
    arrange(symbol) 
# A tibble: 30 x 2 
# symbol value 
# <chr> <int> 
# 1  a  7 
# 2  a  8 
# 3  a  9 
# 4  a 10 
# 5  a 11 
# 6  i  8 
# 7  i  9 
# 8  i 10 
# 9  i 11 
#10  i 12 
# ... with 20 more rows 
+1

織補簡單,呵呵!我只是一直忘記'做'具有多大的力量。試圖玩一點這個問題,但只是不能提出正確的步驟。完善。謝謝! – Gopala

1

你可以使用data.table和所需的行數(基於startend每個symbol)複製df,再經過

library(data.table) 

setDT(df) 
df[rep(1:.N, (end - start + 1))][, value := (start - 1) + (1:.N), by = symbol][] 

# symbol start end value 
# 1:  u  9 14  9 
# 2:  u  9 14 10 
# 3:  u  9 14 11 
# 4:  u  9 14 12 
# 5:  u  9 14 13 
# ... etc 
1

也許你可以使用map2來添加一個我們可以從unnest到所需的結果列。

library(tidyverse) 
df %>% 
    mutate(value = map2(start, end, ~ seq(from = .x, to = .y))) %>% 
    select(symbol, value) %>% 
    unnest() 
#> symbol value 
#> 1  u  9 
#> 2  u  10 
#> 3  u  11 
#> 4  u  12 
#> 5  u  13 
#> 6  u  14 
#> 7  n  6 
#> 8  n  7 
#> 9  n  8 
#> 10  n  9 
#> ...etc