[英]How to group a vector into a list of vectors?
我有一些看起來像這樣的數據(例如假數據):
dressId color
6 yellow
9 red
10 green
10 purple
10 yellow
12 purple
12 red
其中顏色是因子向量。 不能保證該因子的所有可能級別都實際出現在數據中(例如,顏色“藍色”也可能是級別之一)。
我需要一個向量列表,將每件衣服的可用顏色分組:
[[1]]
yellow
[[2]]
red
[[3]]
green purple yellow
[[4]]
purple red
保留連衣裙的 ID 會很好(例如,一個數據框,該列表是第二列,ID 是第一列),但不是必需的。
我寫了一個循環遍歷數據幀行,雖然下一個 ID 相同,但它將顏色添加到向量中。 (我確信數據是按 ID 排序的)。 當第一列中的 ID 發生變化時,它會將向量添加到列表中:
result <- NULL
while(blah blah)
{
some code which creates the vector called "colors"
result[[dressCounter]] <- colors
dressCounter <- dressCounter + 1
}
在努力使所有必要的計數變量都正確之后,我沮喪地發現它不起作用。 第一次, colors
是
[1] yellow
Levels: green yellow purple red blue
它被強制轉換為整數,因此result
變為2
。
在第二次循環重復中, colors
只包含紅色, result
變成了一個簡單的整數向量[1] 2 4
。
在第三次重復中, colors
現在是一個向量,
[1] green purple yellow
Levels: green yellow purple red blue
我得到
result[[3]] <- colors
結果錯誤[[3]] <-顏色:
提供的元素多於替換的元素
我究竟做錯了什么? 有沒有辦法初始化result
所以它不會被轉換為數字向量,而是成為向量列表?
此外,除了“自己動手”之外,還有其他方法可以完成整個事情嗎?
split.data.frame
是一個很好的組織方式; 然后提取顏色分量。
d <- data.frame(dressId=c(6,9,10,10,10,12,12),
color=factor(c("yellow","red","green",
"purple","yellow",
"purple","red"),
levels=c("red","orange","yellow",
"green","blue","purple")))
我認為你想要的版本實際上是這樣的:
ss <- split.data.frame(d,d$dressId)
通過提取顏色分量,您可以獲得更像您請求的列表的內容:
lapply(ss,"[[","color")
除了split
,您還應該考慮aggregate
。 使用c
或I
作為聚合函數來獲取您的list
列:
out <- aggregate(color ~ dressId, mydf, c)
out
# dressId color
# 1 6 yellow
# 2 9 red
# 3 10 green, purple, yellow
# 4 12 purple, red
str(out)
# 'data.frame': 4 obs. of 2 variables:
# $ dressId: int 6 9 10 12
# $ color :List of 4
# ..$ 0: chr "yellow"
# ..$ 1: chr "red"
# ..$ 2: chr "green" "purple" "yellow"
# ..$ 3: chr "purple" "red"
out$color
# $`0`
# [1] "yellow"
#
# $`1`
# [1] "red"
#
# $`2`
# [1] "green" "purple" "yellow"
#
# $`3`
# [1] "purple" "red"
注意:即使“顏色”變量是一個factor
,這也有效,如 Ben 的示例數據(我在上面發布答案時錯過了那個點)但您需要使用I
作為聚合函數而不是c
:
out <- aggregate(color ~ dressId, d, I)
str(out)
# 'data.frame': 4 obs. of 2 variables:
# $ dressId: num 6 9 10 12
# $ color :List of 4
# ..$ 0: Factor w/ 6 levels "red","orange",..: 3
# ..$ 1: Factor w/ 6 levels "red","orange",..: 1
# ..$ 2: Factor w/ 6 levels "red","orange",..: 4 6 3
# ..$ 3: Factor w/ 6 levels "red","orange",..: 6 1
out$color
# $`0`
# [1] yellow
# Levels: red orange yellow green blue purple
#
# $`1`
# [1] red
# Levels: red orange yellow green blue purple
#
# $`2`
# [1] green purple yellow
# Levels: red orange yellow green blue purple
#
# $`3`
# [1] purple red
# Levels: red orange yellow green blue purple
然而,奇怪的是,默認顯示顯示的是整數值:
out
# dressId color
# 1 6 3
# 2 9 1
# 3 10 4, 6, 3
# 4 12 6, 1
假設您的數據框保存在一個名為df
的變量中,那么您可以簡單地使用group_by
並使用dplyr
包的list
函數進行summarize
,如下所示
library('dplyr')
df %>%
group_by(dressId) %>%
summarize(colors = list(color))
應用於您的示例:
df <- tribble(
~dressId, ~color,
6, 'yellow',
9, 'red',
10, 'green',
10, 'purple',
10, 'yellow',
12, 'purple',
12, 'red'
)
df %>%
group_by(dressId) %>%
summarize(colors = list(color))
# dressId colors
# 6 yellow
# 9 red
# 10 green, purple, yellow
# 12 purple, red
恐怕答案應該有點不同,您應該使用以下代碼來完成請求的行為
df %>%
group_by(dressId) %>%
summarize(colors = toString(unique(color)))
所有其他答案都可以完成這項工作,我參加聚會有點晚了,但有些人使用了 dplyr,如果可能的話,我總是盡量遠離 tidyverse,對於這個問題,可以使用基本 R 而不會使 tidyverse 膨脹。 其他一些人通過制作數據框解決了這個問題,這不是標題所說的:)
讓我們創建向量,因為 OP 沒有向我們提供代碼(請注意,OP 需要向量而不是數據幀,盡管您可以使用稍作修改的數據幀來執行此操作):
dressId <- c(6, 9, 10, 10, 10, 12, 12)
color <- c("yellow", "red", "green", "purple", "yellow", "purple", "red")
現在讓我們開始業務並計算 OP 的要求:
我需要一個向量列表,將每件衣服的可用顏色分組:
result <- split(x = color, f = dressId)
result
這將輸出:
$`6` [1] "yellow" $`9` [1] "red" $`10` [1] "green" "purple" "yellow" $`12` [1] "purple" "red"
這是非常簡單直接的。 現在,如果你有不止一對,例如如果你有另一個“紅色”的dressID 12
,那么你可以將split()
的結果傳遞給unique()
:
result <- lapply(result, unique)
如果您將color
作為一個因素,從技術上講它也應該起作用,但它會使result
的每個項目成為一個因素。 以減輕,只需使用unfactor()
從varhandle
包到您系數轉換成非要素矢量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.