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

如何将向dataframe添加新列的自定义函数应用到现有列的子集?

孙玺
2023-03-14

我正在处理一个大型数据集,其中大部分数据被输入两次。这意味着许多变量由成对的列表示:column.1,其中数据由一个人输入;column.2,其中相同的数据由另一个人输入。我想创建一个名为column的“主”列,该列首先从column.1提取,然后如果column.1na,则从column.2提取。

下面是我试图用虚构数据做的一个示例:

mydata <- data.frame(name = c("Sarah","Ella","Carmen","Dinah","Billie"),
                     cheese.1 = c(1,4,NA,6,NA),
                     cheese.2 = c(1,4,3,5,NA),
                     milk.1 = c(NA,2,0,4,NA),
                     milk.2 = c(1,2,1,4,2),
                     tofu.1 = c("yum","yum",NA,"gross", NA),
                     tofu.2 = c("gross", "yum", "yum", NA, "gross"))

例如,下面的代码显示了我希望对单个列对执行的操作的示例

mydata %>% mutate(cheese = ifelse(is.na(cheese.1), cheese.2, cheese.1))

#OUTPUT:

    name cheese.1 cheese.2 milk.1 milk.2 tofu.1 tofu.2 cheese
1  Sarah        1        1     NA      1    yum  gross      1
2   Ella        4        4      2      2    yum    yum      4
3 Carmen       NA        3      0      1   <NA>    yum      3
4  Dinah        6        5      4      4  gross   <NA>      6
5 Billie       NA       NA     NA      2   <NA>  gross     NA

但是,我希望自动化这个过程,而不是手动完成每个过程。下面是我尝试使用要为其创建新的“主”列的列对列表(col.list)来自动化该过程:

col.list = c("cheese","milk","tofu")

lapply(col.list, FUN = function(x) {
  v <- as.name({{x}})
  v.1 <- as.name(paste0({{x}}, ".1"))
  v.2 <- as.name(paste0(({{x}}), ".2"))
  mydata %>% mutate(v = ifelse(is.na({{v.1}}), {{v.2}}, {{v.1}}))
})

#OUTPUT:

[[1]]
    name cheese.1 cheese.2 milk.1 milk.2 tofu.1 tofu.2  v
1  Sarah        1        1     NA      1    yum  gross  1
2   Ella        4        4      2      2    yum    yum  4
3 Carmen       NA        3      0      1   <NA>    yum  3
4  Dinah        6        5      4      4  gross   <NA>  6
5 Billie       NA       NA     NA      2   <NA>  gross NA

[[2]]
    name cheese.1 cheese.2 milk.1 milk.2 tofu.1 tofu.2 v
1  Sarah        1        1     NA      1    yum  gross 1
2   Ella        4        4      2      2    yum    yum 2
3 Carmen       NA        3      0      1   <NA>    yum 0
4  Dinah        6        5      4      4  gross   <NA> 4
5 Billie       NA       NA     NA      2   <NA>  gross 2

[[3]]
    name cheese.1 cheese.2 milk.1 milk.2 tofu.1 tofu.2     v
1  Sarah        1        1     NA      1    yum  gross   yum
2   Ella        4        4      2      2    yum    yum   yum
3 Carmen       NA        3      0      1   <NA>    yum   yum
4  Dinah        6        5      4      4  gross   <NA> gross
5 Billie       NA       NA     NA      2   <NA>  gross gross

这种尝试的问题是:

  1. 新列的名称不正确(它们应该被命名为cheesemilktofu,而不是都被称为v)
  2. 新列不添加到原始数据帧中。我希望程序将一系列新的“主”列添加到dataframe中(col.list中标识的每对列都有一个新列)。

共有1个答案

笪健
2023-03-14

(1)必须将v换到卷边运算符中,并使用:=:

library(dplyr)

col.list <- c("cheese","milk","tofu")

lapply(col.list, FUN = function(x) {
  v <- as.name({{x}})
  v.1 <- as.name(paste0({{x}}, ".1"))
  v.2 <- as.name(paste0(({{x}}), ".2"))
  mydata %>% mutate({{ v }} = ifelse(is.na({{v.1}}), {{v.2}}, {{v.1}}))
})

回报

[[1]]
    name cheese.1 cheese.2 milk.1 milk.2 tofu.1 tofu.2 cheese
1  Sarah        1        1     NA      1    yum  gross      1
2   Ella        4        4      2      2    yum    yum      4
3 Carmen       NA        3      0      1   <NA>    yum      3
4  Dinah        6        5      4      4  gross   <NA>      6
5 Billie       NA       NA     NA      2   <NA>  gross     NA

[...]

这离你想要的输出更近了一步。

library(purrr)
library(dplyr)

col.list %>% 
  map(~mydata %>% 
        select(name, starts_with(.x)) %>% 
        mutate({{ .x }} := ifelse(
          is.na(!!sym(paste0(.x, ".1"))), 
          !!sym(paste0(.x, ".2")), 
          !!sym(paste0(.x, ".1"))
          )
        )
  ) %>% 
  reduce(left_join, by = "name")

这返回

    name cheese.1 cheese.2 cheese milk.1 milk.2 milk tofu.1 tofu.2  tofu
1  Sarah        1        1      1     NA      1    1    yum  gross   yum
2   Ella        4        4      4      2      2    2    yum    yum   yum
3 Carmen       NA        3      3      0      1    0   <NA>    yum   yum
4  Dinah        6        5      6      4      4    4  gross   <NA> gross
5 Billie       NA       NA     NA     NA      2    2   <NA>  gross gross
 类似资料:
  • 本文向大家介绍向Pandas中的现有DataFrame添加新列,包括了向Pandas中的现有DataFrame添加新列的使用技巧和注意事项,需要的朋友参考一下 Pandas 数据框是一种二维数据结构,即,数据以表格的形式在行和列中对齐。可以使用python dict,list和series等创建它。在本文中,我们将看到如何在现有数据框中添加新列。因此,首先让我们使用pandas系列创建一个数据框。

  • 问题内容: 我目前正在尝试从MongoDB中提取数据库,并使用Spark来将其提取到ElasticSearch中。 Mongo数据库具有纬度和经度值,但是ElasticSearch要求将它们强制转换为类型。 Spark中是否可以将and 列复制到or 的新列? 任何帮助表示赞赏! 问题答案: 我假设您从某种平面模式开始,如下所示: 首先让我们创建示例数据: 一种简单的方法是使用udf和case类:

  • 问题内容: 我有以下索引的DataFrame,其中的命名列和行不是连续数字: 我想在现有数据框架中添加新列,并且不想更改数据框架中的任何内容(即,新列的长度始终与DataFrame相同)。 我尝试了不同的版本,但我没有得到我想要的,最多只是错误的结果。如何e在上面的示例中添加列? 问题答案: 使用原始的df1索引创建系列: 编辑2015年 有些人报告使用此代码。 但是,该代码仍可以在当前的熊猫0.

  • 本文向大家介绍在Python中的Pandas中向现有DataFrame添加新列,包括了在Python中的Pandas中向现有DataFrame添加新列的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将学习如何在pandas中向现有DataFrame添加新列。我们可以有不同的方法来添加新列。让我们所有人。 使用列表 我们可以使用该列表添加新列。请按照以下步骤添加新列。 算法 让我们看一个例

  • 那么,如何使用PySpark向现有的DataFrame添加一个新列(基于Python vector)呢?

  • 我创建了一个名为的函数,该函数采用了如图所示的这3个参数,结果是新参数。我想将此函数应用于一个数据帧,其中函数参数是数据帧中的某些列,并希望将函数的输出参数添加为数据帧中的新参数,在数据帧中为每行计算函数。