假设我有存储在数据帧中的水果超市股票调查的结果:转换二进制调查结果字符向量中的R数据帧
stock <- data.frame(
store = c("Asda", "Booths", "Co-op"),
apple = c(1, 0, 0),
banana = c(1, 1, 0),
coconut = c(0, 0, 0)
)
它看起来像
store apple banana coconut
1 Asda 1 1 0
2 Booths 0 1 0
3 Co-op 0 0 0
我的目标是:
我想将上述二元调查结果列转换为每个超级马尔的股票摘要的字符向量KET如下:
store fruits
1 Asda apple, banana
2 Booths banana
3 Co-op
我的解决办法:
步骤1:我用for
环与对应的列名,以取代在二进制列全1:
for(i in names(stock)[2:4]) {
stock[which(stock[[i]] == 1), i] <- i
}
并得到
store apple banana coconut
1 Asda apple banana 0
2 Booths 0 banana 0
3 Co-op 0 0 0
第2步:我用tidyr::unite()
个别水果列连接成一个字符向量列:
library(tidyverse)
stock <- unite(stock, fruits, apple:coconut, sep = ", ")
给我
store fruits
1 Asda apple, banana, 0
2 Booths 0, banana, 0
3 Co-op 0, 0, 0
第3步:我不得不使用stringr :: str_replace_all()删除所有不需要的0和逗号分隔符:
library(stringr)
stock$fruits <- str_replace_all(stock$fruits, "0, |, 0|0", "")
虽然这可以让我得到我想要的结果,但我发现我的解决方案相当笨拙,尤其是循环部分。任何人都可以与我分享一个更有效和直接的解决方案吗?提前谢谢了!
非常感谢您对我的问题提供两种解决方案,同时注意我的问题标签,并为您的额外编码注释清楚地解释事情!虽然我最喜欢的'tidyverse'解决方案非常简洁,但我也对'data.table'替代方案的简洁感到惊讶。 – elarry
@elarry说实话,我更喜欢'data.table'不仅仅是因为它的简洁的代码,而且也是为了解决更大问题的性能原因。例如,看[我的另一个问题的基准](https://stackoverflow.com/a/44755588/3817004)。 – Uwe