将二进制测量结果转换为R数据帧中的字符向量
假设我将超市水果库存调查的结果存储在数据框中:将二进制测量结果转换为R数据帧中的字符向量,r,dataframe,character,binary-data,tidyverse,R,Dataframe,Character,Binary Data,Tidyverse,假设我将超市水果库存调查的结果存储在数据框中: 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 fruits 1 Asda apple, ban
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 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
}
步骤2:我使用tidyr::unite()
将各个水果列连接到一个字符向量列中:
library(tidyverse)
stock <- unite(stock, fruits, apple:coconut, sep = ", ")
步骤3:我必须使用stringr::str_replace_all()删除所有不需要的0和逗号分隔符:
library(stringr)
stock$fruits <- str_replace_all(stock$fruits, "0, |, 0|0", "")
库(stringr)
库存$FROUTS假设商店名称唯一,只有1和0,并且没有缺失值:
library(dplyr)
library(tidyr)
result <- stock %>%
gather(fruit, binary, -store) %>%
mutate(fruit = if_else(binary == 1, fruit, NA_character_)) %>%
select(-binary) %>%
filter(!is.na(fruit)) %>%
group_by(store) %>%
summarize(fruits = paste(fruit, collapse = ", ")) %>%
ungroup() %>%
right_join(stock %>% select(store)) %>%
mutate(fruits = if_else(is.na(fruits), "", fruits))
库(dplyr)
图书馆(tidyr)
结果%
采集(水果,二进制,-存储)%>%
变异(果=if_-else(二进制==1,果,NA_字符))%>%
选择(-binary)%>%
过滤器(!is.na(水果))%>%
分组依据(门店)%>%
汇总(水果=浆糊(水果,折叠=“,”)%%
解组()%>%
右键加入(库存%>%选择(商店))%%>%
变异(水果=如果其他(is.na(水果),“”,水果))
假设存储名称唯一,只有1和0,并且没有缺失值:
library(dplyr)
library(tidyr)
result <- stock %>%
gather(fruit, binary, -store) %>%
mutate(fruit = if_else(binary == 1, fruit, NA_character_)) %>%
select(-binary) %>%
filter(!is.na(fruit)) %>%
group_by(store) %>%
summarize(fruits = paste(fruit, collapse = ", ")) %>%
ungroup() %>%
right_join(stock %>% select(store)) %>%
mutate(fruits = if_else(is.na(fruits), "", fruits))
库(dplyr)
图书馆(tidyr)
结果%
采集(水果,二进制,-存储)%>%
变异(果=if_-else(二进制==1,果,NA_字符))%>%
选择(-binary)%>%
过滤器(!is.na(水果))%>%
分组依据(门店)%>%
汇总(水果=浆糊(水果,折叠=“,”)%%
解组()%>%
右键加入(库存%>%选择(商店))%%>%
变异(水果=如果其他(is.na(水果),“”,水果))
该任务需要将输入数据的格式从宽改为长
虽然问题被明确地标记为tidyverse
,但我想从一个简明的data.table
解决方案开始,该解决方案使用melt()
,我比较熟悉:
library(data.table)
melt(setDT(stock), id.vars = "store")[
value > 0, .(fruits = toString(variable)), keyby = store][.(stock$store)]
它将stock
强制为classdata.table
,并将其从宽格式改为长格式。然后,在随后的聚合中只考虑至少有一个结果的行,其中结果按store
分组toString()
用于聚合,它是paste()
的简明替代方法。为了包括所有的商店,甚至那些没有任何水果的商店,最终的加入权是必需的
按照OP的要求,使用tidyr
和dplyr
软件包中的函数也可以实现相同的目标:
library(magrittr)
stock %>%
tidyr::gather(fruits, , -store) %>%
dplyr::filter(value > 0) %>%
dplyr::group_by(store) %>%
dplyr::summarise(toString(fruits)) %>%
dplyr::right_join(stock %>% dplyr::select(store))
#一个tible:3 x 2
商店`toString(水果)`
1阿斯达苹果、香蕉
2个摊位香蕉
3合作社
这两个结果是等价的
请注意,对tidyverse
函数的引用是明确的,以避免由于混乱的名称空间而产生名称冲突。该任务需要将输入数据的格式从宽改为长
虽然问题被明确地标记为tidyverse
,但我想从一个简明的data.table
解决方案开始,该解决方案使用melt()
,我比较熟悉:
library(data.table)
melt(setDT(stock), id.vars = "store")[
value > 0, .(fruits = toString(variable)), keyby = store][.(stock$store)]
它将stock
强制为classdata.table
,并将其从宽格式改为长格式。然后,在随后的聚合中只考虑至少有一个结果的行,其中结果按store
分组toString()
用于聚合,它是paste()
的简明替代方法。为了包括所有的商店,甚至那些没有任何水果的商店,最终的加入权是必需的
按照OP的要求,使用tidyr
和dplyr
软件包中的函数也可以实现相同的目标:
library(magrittr)
stock %>%
tidyr::gather(fruits, , -store) %>%
dplyr::filter(value > 0) %>%
dplyr::group_by(store) %>%
dplyr::summarise(toString(fruits)) %>%
dplyr::right_join(stock %>% dplyr::select(store))
#一个tible:3 x 2
商店`toString(水果)`
1阿斯达苹果、香蕉
2个摊位香蕉
3合作社
这两个结果是等价的
请注意,对tidyverse
函数的引用是明确的,以避免由于混乱的名称空间而产生名称冲突。非常感谢您在仔细注意我的问题标签的同时,为我的问题提供了两种解决方案,并感谢您额外的编码注释,清楚地解释了问题!虽然我首选的tidyverse
解决方案非常简洁,但我也对data.table
替代方案的简洁性感到惊讶。@elarry老实说,我更喜欢data.table
不仅因为它的代码简洁,而且因为更大问题的性能原因。例如,请参阅。非常感谢您为我的问题提供了两种解决方案,同时对我的问题标签给予了周到的关注,以及您额外的编码注释,清楚地解释了问题!虽然我首选的tidyverse
解决方案非常简洁,但我也对data.table
替代方案的简洁性感到惊讶。@elarry老实说,我更喜欢data.table
不仅因为它的代码简洁,而且因为更大问题的性能原因。例如,请参阅。非常感谢您共享一个用于将二进制数据转换为字符向量的paste()
替代方案-它对于像我这样不知道toString()
函数的人特别有用。:)非常感谢您分享一个将二进制数据转换为字符向量的paste()
替代方案-它对像我这样不知道toString()
函数的人特别有用。:)
library(magrittr)
stock %>%
tidyr::gather(fruits, , -store) %>%
dplyr::filter(value > 0) %>%
dplyr::group_by(store) %>%
dplyr::summarise(toString(fruits)) %>%
dplyr::right_join(stock %>% dplyr::select(store))
# A tibble: 3 x 2
store `toString(fruits)`
<fctr> <chr>
1 Asda apple, banana
2 Booths banana
3 Co-op <NA>