当前位置: 首页 > 知识库问答 >
问题:

在dplyr中使用列表列函数进行突变

郎睿
2023-03-14

我试图计算在一个Tibble中源向量和比较向量之间的Jaccard相似度。

source_vec <- c('a', 'b', 'c')

df_comp <- tibble(names_ = c("b d f", "u k g", "m o c"),
              names_vec = strsplit(names_, ' '))

df_comp_jaccard <- df_comp %>%
   dplyr::mutate(jaccard_sim = length(intersect(names_vec, source_vec))/length(union(names_vec, source_vec)))

jaccard_sim中的所有值都为零。但是,如果我们运行类似这样的东西,我们得到第一个条目的正确的Jaccard相似度为0.2:

a <- length(intersect(source_vec, df_comp[[1,2]]))
b <- length(union(source_vec, df_comp[[1,2]]))
a/b

共有1个答案

林烨华
2023-03-14

您可以简单地以行方式添加

df_comp_jaccard <- df_comp %>%
  rowwise() %>%
  dplyr::mutate(jaccard_sim = length(intersect(names_vec, source_vec))/
                              length(union(names_vec, source_vec)))

# A tibble: 3 x 3
  names_ names_vec jaccard_sim
   <chr>    <list>       <dbl>
1  b d f <chr [3]>         0.2
2  u k g <chr [3]>         0.0
3  m o c <chr [3]>         0.2

使用rowwise您可以得到一些人在使用mutate时所期望的直观行为:“对每一行执行此操作”。

不使用rowwise意味着您利用了向量化的函数,这要快得多,这就是为什么它是默认的,但是如果您不小心,可能会产生意想不到的结果。

我将用几个例子来说明:

有时结果是相同的,使用诸如粘贴这样的矢量化函数:

tibble(a=1:10,b=10:1) %>% mutate(X = paste(a,b,sep="_"))
tibble(a=1:10,b=10:1) %>% rowwise %>% mutate(X = paste(a,b,sep="_"))
# # A tibble: 5 x 3
#       a     b     X
#   <int> <int> <chr>
# 1     1     5   1_5
# 2     2     4   2_4
# 3     3     3   3_3
# 4     4     2   4_2
# 5     5     1   5_1

有时情况不同,对于未向量化的函数,例如max:

tibble(a=1:5,b=5:1) %>% mutate(max(a,b))
# # A tibble: 5 x 3
#       a     b `max(a, b)`
#   <int> <int>       <int>
# 1     1     5           5
# 2     2     4           5
# 3     3     3           5
# 4     4     2           5
# 5     5     1           5

tibble(a=1:5,b=5:1) %>% rowwise %>% mutate(max(a,b))
# # A tibble: 5 x 3
#       a     b `max(a, b)`
#   <int> <int>       <int>
# 1     1     5           5
# 2     2     4           4
# 3     3     3           3
# 4     4     2           4
# 5     5     1           5

请注意,在这种情况下,您不应该在实际情况中使用rowwise,而是使用pmax,该pmax:

tibble(a=1:5,b=5:1) %>% mutate(pmax(a,b))
# # A tibble: 5 x 3
#       a     b `pmax(a, b)`
#   <int> <int>        <int>
# 1     1     5            5
# 2     2     4            4
# 3     3     3            3
# 4     4     2            4
# 5     5     1            5

Intersect就是这样的函数,你给这个函数提供一个包含向量的列表列和一个其他向量,这两个对象没有交集。

 类似资料:
  • 我已经更新了dplyr(现在是0.7.1),我的很多旧代码都不能用了,因为mutate_each已经被弃用了。我曾经用mutate_each做类似这样的事情(代码如下),使用列索引。我会在数百个专栏中这样做。而我就是搞不清楚如何用mutate_at正确使用vars参数。我看到的所有例子都使用了列名...我不想这么做。我确信这是一个简单的答案,但是我已经花了太多的时间试图弄明白它,并且将非常感谢一些

  • 我是碰撞检测新手,在游戏原型中遇到了一些问题。我已经做了好几天了。经过一些阅读和辅导,我仍然不明白我做错了什么,所以这里的其他人应该能够解释我做错了什么。 游戏运行时,屏幕上有10个绿色矩形(NPC)和1个红色矩形(吸血鬼)。作为一个起点,我希望吸血鬼“喝血”,当它通过愚蠢的运气随机穿过npc时。如果我不注释掉冲突检测方法,代码中就会出现一个nullpointexception。 公共类屏幕扩展J

  • 我正在尝试使用创建一个新列,该列的值基于特定的列。 最后一个数据帧示例(我正在尝试创建): 这个问题基本上与此相反:dplyr-mutate:使用动态变量名。我不能使解决方案适应我的问题。

  • 我有一个名称重复的数据集。如果名称重复,我想创建一个值为1(TRUE)或0(FALSE)的新列。 这是我使用的代码: 或者 然而,我得到了上面可以看到的错误。 另一个想法是使用group_by,然后计算计数。喜欢: 但是,它不能返回原始数据帧后group_by

  • 我试图计算许多列的行平均值。有人能解释一下为什么下面的代码只计算代码中两个变量(var_1和var_13)的平均值,而不是所有13列的平均值吗?

  • 我想使用dplyr的mutate_at函数将一个函数应用于数据帧中的几个列,其中该函数输入它直接应用到的列以及数据帧中的另一列。 作为一个具体的例子,我希望改变以下数据帧 与调用类似 返回一个看起来像这样的数据框 所需的调用将类似于以下对的调用: 我知道这可以通过几种方式在base R中实现,但为了可读性、与数据库的接口等,我特别希望使用dplyr的mutate\u at函数来实现这一目标。 在d