R 如果列中存在值,请按行检查,并按行更新新列

R 如果列中存在值,请按行检查,并按行更新新列,r,R,在R中,如何检查每行列表中的任何值(例如2、3或4)是否存在于三列中的任何一列中,然后在第四列中更改该行 假设我有一个df: A B C D 1 1 1 2 1 1 3 1 1 我想写(没有for循环) 如果第n行(列A或B或C)==2或3或4,则D[1,]=1,否则=0 基本上是按行检查我的数字是否存在于三个特定列中的任何一列中,如果存在,则用1(如果不是0)更新第四列 谢谢,只有这三个条件你才能做到 df1$D <- as.integer(rowSums(df1 == 2 |

在R中,如何检查每行列表中的任何值(例如2、3或4)是否存在于三列中的任何一列中,然后在第四列中更改该行

假设我有一个df:

 A B C D
 1 1 1
 2 1 1
 3 1 1
我想写(没有for循环) 如果第n行(列A或B或C)==2或3或4,则D[1,]=1,否则=0

基本上是按行检查我的数字是否存在于三个特定列中的任何一列中,如果存在,则用1(如果不是0)更新第四列


谢谢,

只有这三个条件你才能做到

df1$D <- as.integer(rowSums(df1 == 2 | df1 == 3 | df1 == 4) >= 1) # or maybe df1 >=2 & df1 <= 4
df1
#  A B C D
#1 1 1 1 0
#2 2 1 1 1
#3 3 1 1 1

df1$D=1)#或者df1>=2&df1这里有一种使用
数据的方法。表

library(data.table)
test <- data.table(A = c(1, 2,3), 
                   B = c(1, 1, 1), 
                   C = c(1, 1, 1))
checkValues <- c(2, 3, 4)

test[, c("D"):= Reduce(`|`, lapply(.SD, function(x){x %in% checkValues}))]

test
   A B C     D
1: 1 1 1 FALSE
2: 2 1 1  TRUE
3: 3 1 1  TRUE
库(data.table)

测试以下是如何使用
dplyr

library(dplyr)
test <- data.frame(A = c(1, 2, 3), 
                   B = c(1, 1, 1), 
                   C = c(1, 1, 1))

testColumns <- c(2, 3, 4)                         # Values you want to flag 
这为我们提供了下表:

print(test)
## A tibble: 3 x 4
#      A     B     C     D
#  <dbl> <dbl> <dbl> <dbl>
#1     1     1     1     0
#2     2     1     1     1
#3     3     1     1     1
打印(测试)
##一个tibble:3x4
#A、B、C、D
#     
#1     1     1     1     0
#2     2     1     1     1
#3     3     1     1     1
以下是我们使用的一些函数的有用链接:



tidyverse
中执行此操作的一种方法:

df %>%
 rowid_to_column() %>% #Creating an unique row ID
 gather(var, val, -rowid) %>% #Transforming the data from wide to long
 group_by(rowid) %>% #Grouping
 mutate(D = ifelse(any(val %in% c(2, 3, 4)), 1, 0)) %>% #Testing whether any value from a given row is in the specified list 
 spread(var, val) %>% #Returning the data to wide format
 ungroup() %>%
 select(-rowid) #Deleting the redundant variable

      D     A     B     C
  <dbl> <int> <int> <int>
1    0.     1     1     1
2    1.     2     1     1
3    1.     3     1     1
df%>%
rowid_to_column()%>%#创建唯一的行ID
聚集(var,val,-rowid)%>%#将数据从宽转换为长
分组依据(rowid)%>%#分组
mutate(D=ifelse(any(val%in%c(2,3,4)),1,0))%>%#测试给定行中的任何值是否在指定列表中
价差(var,val)%>%#将数据返回到宽格式
解组()%>%
选择(-rowid)#删除冗余变量
D A B C
1    0.     1     1     1
2    1.     2     1     1
3    1.     3     1     1

为感兴趣的列名和数字参数化

library(tidyverse)

data <-
  data.frame(
    A = c(1, 2, 3), 
    B = c(1, 1, 1), 
    C = c(1, 1, 1)
  )

nums <- c(2, 3, 4)
cols <- c('A', 'B', 'C')

data$D <-
  data[, cols] %>%
  map(~.x %in% nums) %>%
  reduce(`|`)
库(tidyverse)

数据您可以使用
应用

vec <- 2:4
df1$D <- apply(df1,1, function(x) any(vec %in% x)) +0
#   A B C D
# 1 1 1 1 0
# 2 2 1 1 1
# 3 3 1 1 1
数据

df1 <- structure(list(A = 1:3, B = c(1L, 1L, 1L), C = c(1L, 1L, 1L)), .Names = c("A", 
"B", "C"), class = "data.frame", row.names = c(NA, -3L))
df1 <- data.frame(A = c(1, 2,3), 
                   B = c(1, 1, 1), 
                   C = c(1, 1, 1))

df1这是解决一个简单问题的非常复杂的方法。使用
rowwise()
和mutate将是一种更简单的方法。@OTStats您的方法肯定比我的更优雅、更直接。但是,我认为看到针对同一问题的不同方法是很好的。我完全同意-有助于解决许多不同类型的问题。使用
data.table
的一个优点是,您可以使用
.SD
而不是指定每个列名,因此,在具有大量列的表上执行此操作同样容易。当然,这可能与
dplyr
有关,我不太熟悉:)这是一个好问题,我不确定这将如何工作。看看它!谢谢你的帮助。我是否必须创建一个新的数据帧,或者我可以将D列添加到“test”中?我将运行多个测试,创建8个新列,并将其附加到数据框中。在这种情况下,您可以利用
%%
,这称为复合分配管道操作符。这与常规管道操作符
%%>%%
的工作原理类似,但它会将结果分配回原始对象。请参阅此链接以获取帮助:我使用前面提到的转发管道更新了我的响应。
library(tidyverse)
df1 %>% mutate(D = pmap_int(.,~any(vec %in% .)))
#   A B C D
# 1 1 1 1 0
# 2 2 1 1 1
# 3 3 1 1 1
df1 <- data.frame(A = c(1, 2,3), 
                   B = c(1, 1, 1), 
                   C = c(1, 1, 1))