R:将以下代码转换为 DPLYR

Posted

技术标签:

【中文标题】R:将以下代码转换为 DPLYR【英文标题】:R: Converting the Following Code to DPLYR 【发布时间】:2022-01-15 15:04:26 【问题描述】:

我正在使用 R 编程语言。我有下表:

age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)

head(testframe)

  age height height2 gender gender2
1  18   76.1    76.1      M       M
2  19   77.0    77.0      F       F
3  20   78.1    78.1      M       M
4  21   78.2    78.2      M       M
5  22   78.8    78.8      F       F
6  23   79.7    79.7      F       F

在上表中,我想删除具有相同条目但名称不同的列。这可以按如下方式完成(在 Base R 中):

no_dup = testframe[!duplicated(as.list(testframe))]

 head(no_dup)
  age height gender
1  18   76.1      M
2  19   77.0      F
3  20   78.1      M
4  21   78.2      M
5  22   78.8      F
6  23   79.7      F

我的问题:有谁知道如何将上述代码testframe[!duplicated(as.list(testframe)) 转换为“DPLYR”命令?这可能吗?

谢谢!

【问题讨论】:

您可以使用管道:testframe %>% filter(. %>% as.list %>% duplicated %>% `!`),但在这种情况下,将数据框用作list 是有意义的,dplyr 用于工作数据框,而不是列表。 @Gregor Thomas:谢谢你的回复!我会试试这个! 但我会指出我评论中的代码有点半开玩笑。除了管道(其中大部分仍然是嵌套的!)之外,唯一的变化是将 [ 替换为 filter @Gregor Thomas:谢谢你的回复!为什么你认为你评论中的代码“有点半开玩笑:?我不确定你在第二句话中的意思 - 如果你有时间,你能告诉我你指的是什么替代品吗?谢谢! 嗯,我猜. 不是这样工作的。我的“舌头在脸颊”评论是因为我所做的几乎所有事情都是将!duplicated(as.list()) 更改为as.list %>% duplicated %>% `!`,它仍然不使用任何dplyr 函数。所以它使用来自magrittr 包的管道,但我(尝试)使用的唯一dplyr 函数是filter 【参考方案1】:

这是使用tidyverse 的一个选项。我使用purrr::map将每一列转换为一个列表,然后我找到了没有重复的列表。对于dplyr::select,您不能使用逻辑向量,因此我们可以使用which 仅返回TRUE 列(即不重复)。然后,我们可以使用索引值来选择列。

library(tidyverse)

testframe %>%
  dplyr::select(., which(purrr::map(., c) %>%
                           duplicated(.) %>%
                           `!`))

输出

   age height gender
1   18   76.1      M
2   19   77.0      F
3   20   78.1      M
4   21   78.2      M
5   22   78.8      F
6   23   79.7      F
7   24   79.9      M
8   25   81.1      M
9   26   81.2      F
10  27   81.8      M
11  28   82.8      F
12  29   83.5      M

你也可以不用purrr

testframe %>%
  dplyr::select(., which(as.list(.) %>%
                           duplicated %>%
                           `!`))

只是为了好玩,这里我只使用tidyverse(虽然更冗长)。它还需要多次旋转数据框。

testframe %>%
  tibble::rownames_to_column() %>%
  dplyr::mutate_all(as.character) %>%
  tidyr::pivot_longer(-rowname) %>%
  tidyr::pivot_wider(names_from = rowname, values_from = value) %>%
  dplyr::distinct_at(vars(-name), .keep_all = TRUE) %>%
  tidyr::pivot_longer(-name, names_to = "rowname", values_to = "value") %>%
  tidyr::pivot_wider(names_from = name, values_from = value) %>%
  dplyr::select(-rowname)

数据

testframe <-
  structure(
    list(
      age = 18:29,
      height = c(76.1, 77, 78.1, 78.2,
                 78.8, 79.7, 79.9, 81.1, 81.2, 81.8, 82.8, 83.5),
      height2 = c(76.1,
                  77, 78.1, 78.2, 78.8, 79.7, 79.9, 81.1, 81.2, 81.8, 82.8, 83.5),
      gender = c("M", "F", "M", "M", "F", "F", "M", "M", "F", "M",
                 "F", "M"),
      gender2 = c("M", "F", "M", "M", "F", "F", "M", "M",
                  "F", "M", "F", "M")
    ),
    class = "data.frame",
    row.names = c(NA, -12L)
  )

【讨论】:

@Andrew Gillreath-Brown:非常感谢您的回答!我通过“DBPLYR”命令传递了您的代码:航班 % dplyr::select(., which(as.list(.) %>% 重复 %>% !)) %>% show_query() 这将返回以下与您编写的代码相对应的 SQL 语句(由于某种原因,缺少“性别”变量):SELECT age, height FROM testframe 最终,我想在位于服务器上的表上使用此代码: 库(RODBC);库(sqldf); con = odbcConnect("一些名字", uid = "一些 id", pwd = "abc"); sample_query = sqlQuery(con, "SELECT age, height FROM testframe") @stats555 我刚刚添加了另一种可能性(尽管它更加冗长)。本质上,它需要多次旋转数据,这允许使用dplyr::distinct 而不是duplicated。它可能会更好地转换为DBPLYR,但我不确定。

以上是关于R:将以下代码转换为 DPLYR的主要内容,如果未能解决你的问题,请参考以下文章

R dplyr:将剪切和粘贴转换为调用函数

将 Stata 转换为 R - 重新编码

将多个png转换为gif作为R中的动画

R - 将事件日志(异步日志)转换为时间序列(同步日志)

用R的dplyr进行数据转换

R语言dplyr包使用recode函数进行数据列内容编码转换实战:类似于pandas中的map函数(例如,将内容从字符串映射到数值)