我想要在列之间匹配相似的单词。

9
1.0 2.0 3.0
loud complaint problems
pain stress confused
dull pain stress

这是我的数据集,我想重新组织行,以便如果每列中都出现一个单词,则将其转移到相应的行。例如

1.0 2.0 3.0
loud NA NA
pain pain NA
dull NA NA
NA complaint NA
NA stress stress
NA NA confused
NA NA problems

等等,这样每个单词都有自己的一行,如果该行中的单词出现在列中,则与其他列匹配

我一直在寻找如何做到这一点,但找不到好的代码。一个想法是创建一个包含所有出现单词的列表,然后尝试将它们与每个列匹配,但仍然没有找到相应的代码。

4个回答

8

我们可以在base R中使用match——从unlist的数据中获取unique元素,作为vector,循环遍历列,获取匹配元素的索引,将索引替换为匹配元素,并在长度处理后转换为data.frame。

v1 <- unique(unlist(df1))
lst1 <- lapply(df1, \(x) 
   {i1 <- match(x, v1)
   replace(rep(NA, max(i1)), i1, v1[i1])
 })
list2DF(lapply(lst1, `length<-`, max(lengths(lst1))))
 1.0       2.0      3.0
1 loud      <NA>     <NA>
2 pain      pain     <NA>
3 dull      <NA>     <NA>
4 <NA> complaint     <NA>
5 <NA>    stress   stress
6 <NA>      <NA> problems
7 <NA>      <NA> confused

数据

df1 <- structure(list(`1.0` = c("loud", "pain", "dull"), `2.0` = c("complaint", 
"stress", "pain"), `3.0` = c("problems", "confused", "stress"
)), class = "data.frame", row.names = c(NA, -3L))


1
list2DF 中的第二个 lapply 不是必需的;您可以只使用 nrow 参数:list2DF(lst1, nrow = max(lengths(lst1)) - rps1227

4

这是一个 tidyverse 版本。

suppressMessages(library(tidyverse))
x = tibble(`1.0` = c("loud", "pain", "dull"),
           `2.0` = c("complaint", "stress", "pain"),
           `3.0` = c("problems", "confused", "stress"))

x %>% 
  gather("version", "value") %>% 
  mutate(id = value) %>% 
  spread(version, value) %>% 
  select(-id)
#> # A tibble: 7 x 3
#>   `1.0` `2.0`     `3.0`   
#>   <chr> <chr>     <chr>   
#> 1 <NA>  complaint <NA>    
#> 2 <NA>  <NA>      confused
#> 3 dull  <NA>      <NA>    
#> 4 loud  <NA>      <NA>    
#> 5 pain  pain      <NA>    
#> 6 <NA>  <NA>      problems
#> 7 <NA>  stress    stress

reprex package (v2.0.0)于2023-04-11创建

如果您需要按出现顺序排列行,可以将第二个语句更改为

mutate(id = fct_inorder(value)) %>% 

注意:函数gatherspread已被pivot_longerpivot_wider函数取代。在我看来,旧的函数使用起来稍微简单一些,并且对于这种情况已经足够好了。新的函数则更加强大。


4

快速 + 高效的 data.table 解决方案:

x <- data.table(`1.0` = c("loud", "pain", "dull"),
           `2.0` = c("complaint", "stress", "pain"),
           `3.0` = c("problems", "confused", "stress"))

dcast(unique(melt(x, measure.vars = names(x))), value ~ variable)

       value  1.0       2.0      3.0
1: complaint <NA> complaint     <NA>
2:  confused <NA>      <NA> confused
3:      dull dull      <NA>     <NA>
4:      loud loud      <NA>     <NA>
5:      pain pain      pain     <NA>
6:  problems <NA>      <NA> problems
7:    stress <NA>    stress   stress

1

这里是使用 stack + reshape 的基本 R 选项

reshape(
  transform(stack(df), v = values),
  direction = "wide",
  idvar = "values",
  timevar = "ind"
)[-1]

这提供了

  v.x1      v.x2     v.x3
1 loud      <NA>     <NA>
2 pain      pain     <NA>
3 dull      <NA>     <NA>
4 <NA> complaint     <NA>
5 <NA>    stress   stress
7 <NA>      <NA> problems
8 <NA>      <NA> confused

数据

> dput(df)
structure(list(x1 = c("loud", "pain", "dull"), x2 = c("complaint", 
"stress", "pain"), x3 = c("problems", "confused", "stress")), class = "data.frame", row.names = c(NA,
-3L))

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