【问题标题】:How to assign values to a new column in R depending on values from other columns如何根据其他列的值将值分配给 R 中的新列
【发布时间】:2020-10-15 16:43:38
【问题描述】:

在我的数据框中创建一个 > 900,000 行的新列,我希望将值作为该列

  1. NA 如果 任何 列中的值是 NA
df$newcol[is.na(df$somecol_1) | is.na(df$somecol_2) | is.na(df$somecol_3)] <- NA
  1. 0 如果一组列中的所有值都是0
df$newcol[df$somecol_1==0 & df$somecol_2==0 & df$somecol_3==0] <- 0
  1. 1 如果一组列中的任何个值是1,而没有一个是NA。这是棘手的部分,因为它与我的 10 列创建了无数的组合。整个数据框有 >50 列,其中我有 10 列对此过程感兴趣,这里我只展示三个:
df$newcol[df$somecol_1==1 & df$somecol_2==0 & df$somecol_3==0] <- 1
df$newcol[df$somecol_1==1 & df$somecol_2==1 & df$somecol_3==0] <- 1
df$newcol[df$somecol_1==1 & df$somecol_2==1 & df$somecol_3==1] <- 1
df$newcol[df$somecol_1==0 & df$somecol_2==1 & df$somecol_3==0] <- 1
df$newcol[df$somecol_1==0 & df$somecol_2==1 & df$somecol_3==1] <- 1
df$newcol[df$somecol_1==0 & df$somecol_2==0 & df$somecol_3==1] <- 1
df$newcol[df$somecol_1==1 & df$somecol_2==0 & df$somecol_3==1] <- 1

我觉得我想多了,一定有办法让 3 更容易吗?如上所示,编写不同的列组合将永远花费十个。由于数据集很大,循环会变得太慢。

虚拟数据:

df <- NULL
df$somecol_1 <- c(1,0,0,NA,0,1,0,NA,1,1)
df$somecol_2 <- c(NA,1,0,0,0,1,0,NA,0,0)
df$somecol_3 <- c(0,0,0,0,0,0,0,0,0,0)
df <- as.data.frame(df)

基于以上,我希望新列是

df$newcol <- c(NA,1,0,NA,0,1,0,NA,1,1)

【问题讨论】:

  • 您的虚拟数据不起作用。你永远不会创建dfsomecol_3 有 11 个值,而其他的有 10 个。
  • 抱歉,已编辑

标签: r


【解决方案1】:
as.numeric(rowSums(df) >= 1) 
#[1] NA  1  0 NA  0  1  0 NA  1  1

rowSums 将给出NA 如果有任何缺失值。如果所有值都为 0,则为 0,否则为 1(假设您的数据全部为 NA01)。

(使用akrun的样本数据)

【讨论】:

  • 这是个好方法。没想到
  • 我相信rowSums 适用于数据框中的整行。我有兴趣使用选定数量的列。在我的问题中也进行了编辑。
  • @pha 您可以在子集上使用rowSums(或任何其他方法)。例如,cols_to_sum = c("somecol_1", "somecol_2", "somecol_3"),然后是 as.numeric(rowSums(df[cols_to_sum]) &gt;= 1)。您只需要指明要考虑的列的名称或索引。
  • @pha 您可以手动输入列索引,键入列名,使用paste() 构造列名,使用grep 和正则表达式模式来提取列名...任何最简单的方法.
【解决方案2】:

我们可以使用rowSums

nm1 <- grep('somecol', names(df))
df$newcol <- NA^(rowSums(is.na(df[nm1])) > 0) *(rowSums(df[nm1], na.rm = TRUE) > 0)
df$newcol
#[1] NA  1  0 NA  0  1  0 NA  1  1

数据

df <- structure(list(somecol_1 = c(1, 0, 0, NA, 0, 1, 0, NA, 1, 1), 
    somecol_2 = c(NA, 1, 0, 0, 0, 1, 0, NA, 0, 0), somecol_3 = c(0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0)), class = "data.frame", row.names = c(NA, 
-10L))

【讨论】:

  • 这适用于整个数据框,而不是我需要的选定数量的列。我现在已经在问题中澄清了这一点。
  • @pha 更新了帖子
【解决方案3】:
df$newcol = ifelse(apply(df,1,sum)>=1,1,0)

应该做的伎俩。首先,apply 将对每一行求和,然后: 每当一行中有NA 值时(第一种情况),任何操作都将返回 NA;当只有 0 时(第 2 种情况),总和为 0(女巫不是&gt;=1) 并且 ifelse 第三个参数使新条目为 0;并且当至少有一个 1 时,总和等于或大于 1 ifelse 第二个参数使新条目成为 1。

编辑:由于您只想在某些列中运行这些条件 - 例如其列 1-7、9 和 23-24 - 您只能在 df 的那部分中使用代码:

df$newcol = as.numeric(rowSums(df[,c(1:7,9,23:24)])>=1)

OBS:我使用了 Akrun 和 Gregor 回答的简化代码。

如果您愿意,可以按名称选择列:Extracting specific columns from a data frame

【讨论】:

  • 谢谢,但这将适用于整个数据框。我对数据框中的选定列数感兴趣。我现在已经在我的问题中澄清了这一点。
猜你喜欢
  • 2022-11-30
  • 2022-11-16
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多