如何将一行["A, B, C", "7"]转换为三行["A", "7"], ["B", "7"], ["C", "7"]?

3
想象一下下面的表格
元素 频率
A 14
A, B 7
A, C 8
A, B, C 1
B, C 3
B 11
C 6

我该如何将它转换为一个表格,其中我将每个元素隔离并求和频率。

在这种情况下,结果应该是

术语 频率
A 30
B 22
C 18

我考虑使用一个巨大的case_when(我有比三个元素更多)来搜索整个表格并求和它们所在行的频率,但这太复杂了。

我考虑像这样分行:

Elem Freq
A 14
A 7
B 7
A 8
C 8
A 1
B 1
C 1
B 3
C 3
B 11
C 6

然后将其分组并求和,但我不知道如何做

3个回答

6
你可以尝试使用separate_longer_delim,然后再使用summarise
library(dplyr)
library(tidyr)

df %>%
    separate_longer_delim(Elem, ", ") %>%
    summarise(Freq = sum(Freq), .by = Elem)

你将获得
  Elem Freq
1    A   30
2    B   22
3    C   18

2
separate_rows(Elem, sep=", ")在这种情况下也是有效的。 - undefined
@JilberUrbina 是的,那也可以 :) - undefined
谢谢 @ThomasIsCoding 和 @jilber-urbina!这正是我在寻找的。 - undefined

2
使用 strsplitxtabs
> Map(data.frame, strsplit(dat$Elem, ',\\s*'), dat$Freq) |> lapply(setNames, names(dat)) |> 
+   do.call(what='rbind') |> setNames(names(dat)) |> xtabs(Freq ~ Elem, data=_) |> as.data.frame()
  Elem Freq
1    A   30
2    B   22
3    C   18

2
另一种基于R的解决方案
> tmp <- stack(setNames(strsplit(df$Elem,', '), df$Freq)) 
> tmp[,"ind"] <- as.numeric(as.character(tmp[,"ind"]))
> aggregate(ind ~ values, FUN = sum, data = tmp)
  values ind
1      A  30
2      B  22
3      C  18

数据:

structure(list(Elem = c("A", "A, B", "A, C", "A, B, C", "B, C", 
"B", "C"), Freq = c(14L, 7L, 8L, 1L, 3L, 11L, 6L)), class = "data.frame", row.names = c(NA, 
-7L))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接