在R中查找数据帧中一组列上一列的值
我正在努力寻找一个data.frame的其他列中一列的值。如果有人能帮助我,我将不胜感激。以下是我的数据的简化形式:在R中查找数据帧中一组列上一列的值,r,R,我正在努力寻找一个data.frame的其他列中一列的值。如果有人能帮助我,我将不胜感激。以下是我的数据的简化形式: library(data.table) df<-data.table(personid<-c(101, 102, 103, 104, 105, 201, 202, 203, 301, 302, 401), hh_id<-c(1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4), fatherid<-c(NA, NA
library(data.table)
df<-data.table(personid<-c(101, 102, 103, 104, 105, 201, 202, 203, 301, 302, 401),
hh_id<-c(1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4),
fatherid<-c(NA, NA, 101, 101, 101, NA, NA, 201, NA, NA, NA),
fatherid_1<-c(NA,101, 101, 101, NA, NA, 201, NA, NA, NA, NA),
fatherid_2<-c(101, 101, 101, NA, NA, 201, NA, NA, NA, NA, NA),
fatherid_3<-c(101, 101, NA, NA, NA, NA, NA, NA, NA, NA, NA),
fatherid_4<-c(101, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
fatherid_5<-c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA))
但是我需要一些东西来自动完成,超过17列,比如fatherid_1
,还有很多行
如果你想了解我计算的意义,我正在尝试构建家庭网格,而不只是使用同一行中的信息
提前非常感谢 OP的数据集是一个
数据表
对象。我们可以使用data.table
方法。循环“fatherid”列,检查“personid”是否等于列值,并将减少为单个向量
library(data.table)
df[, result := +(Reduce(`|`, lapply(.SD, function(x)
x == personid & !is.na(x)))), .SDcols = patterns('fatherid')]
-输出
df
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
OP的数据集是一个data.table
对象。我们可以使用data.table
方法。循环“fatherid”列,检查“personid”是否等于列值,并将减少为单个向量
library(data.table)
df[, result := +(Reduce(`|`, lapply(.SD, function(x)
x == personid & !is.na(x)))), .SDcols = patterns('fatherid')]
-输出
df
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
两种tidyverse解决方案:
1-)您可以使用dplyr的新的if_any()
,==
和tidyr的替换_na()
if_any()
无需使用rowwise()
或reduce()
/reduce()
:
2-)在rowwise()
操作中,您可以应用一个函数,使用map()
、c_overs()
和%In%
检查所有选定列的条件,这将生成一个逻辑向量。然后可以在同一个调用中折叠/reduce()
d
library(purrr)
library(dplyr)
df%>%rowwise()%>%mutate(result=as.integer(reduce(map(c_across(fatherid_1:fatherid_5), ~. %in% personid), `|`)))
或使用管道,为清晰起见:
#option 1
df%>%rowwise()%>%
mutate(result=map(c_across(fatherid_1:fatherid_5), ~. %in% personid)%>%
reduce(`|`)%>%
as.integer())
#option 2
df%>%rowwise()%>%
mutate(result=map_int(c_across(fatherid_1:fatherid_5), ~. %in% personid)%>%
reduce(max))
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
两种tidyverse解决方案:
1-)您可以使用dplyr的新的if_any()
,==
和tidyr的替换_na()
if_any()
无需使用rowwise()
或reduce()
/reduce()
:
2-)在rowwise()
操作中,您可以应用一个函数,使用map()
、c_overs()
和%In%
检查所有选定列的条件,这将生成一个逻辑向量。然后可以在同一个调用中折叠/reduce()
d
library(purrr)
library(dplyr)
df%>%rowwise()%>%mutate(result=as.integer(reduce(map(c_across(fatherid_1:fatherid_5), ~. %in% personid), `|`)))
或使用管道,为清晰起见:
#option 1
df%>%rowwise()%>%
mutate(result=map(c_across(fatherid_1:fatherid_5), ~. %in% personid)%>%
reduce(`|`)%>%
as.integer())
#option 2
df%>%rowwise()%>%
mutate(result=map_int(c_across(fatherid_1:fatherid_5), ~. %in% personid)%>%
reduce(max))
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
我们还可以使用purr
包中的pmap
使用以下解决方案:
library(dplyr)
library(purrr)
df %>%
mutate(result = pmap_dbl(., ~ {x <- c(...)[-c(1, 2)];
if_else(all(x[!is.na(x)] != c(...)[1]) | all(is.na(x)), 0, 1)}))
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
库(dplyr)
图书馆(purrr)
df%>%
mutate(result=pmap_dbl(,{x我们也可以使用pmap
frompurr
package的以下解决方案:
library(dplyr)
library(purrr)
df %>%
mutate(result = pmap_dbl(., ~ {x <- c(...)[-c(1, 2)];
if_else(all(x[!is.na(x)] != c(...)[1]) | all(is.na(x)), 0, 1)}))
personid hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 result
1: 101 1 NA NA 101 101 101 NA 1
2: 102 1 NA 101 101 101 NA NA 0
3: 103 1 101 101 101 NA NA NA 0
4: 104 1 101 101 NA NA NA NA 0
5: 105 1 101 NA NA NA NA NA 0
6: 201 2 NA NA 201 NA NA NA 1
7: 202 2 NA 201 NA NA NA NA 0
8: 203 2 201 NA NA NA NA NA 0
9: 301 3 NA NA NA NA NA NA 0
10: 302 3 NA NA NA NA NA NA 0
11: 401 4 NA NA NA NA NA NA 0
库(dplyr)
图书馆(purrr)
df%>%
mutate(result=pmap_dbl(,{x如果您不想使用行方式
,那么这也可以是一种替代方法
库(dplyr)
df%%>%分组依据(personid)%%>%
变异(res=sum(cur_group()%在%cur_data()中)
#A tibble:11 x 9
#组:personid[11]
人形hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 res
1 101 1 NA 101 101 NA 1
2 102 1 NA 101 101 NA 0
3 103 1 101 101 NA NA 0
4 104 1 101 101 NA NA NA 0
5105110Na0
62012 NA NA 201 NA NA 1
7 202 2 NA 201 NA NA 0
8 203 2 201 NA NA 0
9 301 3 NA NA NA 0
10302 3钠钠钠钠0
11 401 4不适用不适用不适用0
由(v2.0.0)于2021-06-09创建
如果您想安全地排除hh\u id
您可以使用
df %>% group_by(personid) %>%
mutate(res = sum(cur_group() %in% cur_data()[-1]))
如果您不想使用行方式
,那么这也可以是一种替代方法
库(dplyr)
df%%>%分组依据(personid)%%>%
变异(res=sum(cur_group()%在%cur_data()中)
#A tibble:11 x 9
#组:personid[11]
人形hh_id fatherid fatherid_1 fatherid_2 fatherid_3 fatherid_4 fatherid_5 res
1 101 1 NA 101 101 NA 1
2 102 1 NA 101 101 NA 0
3 103 1 101 101 NA NA 0
4 104 1 101 101 NA NA NA 0
5105110Na0
62012 NA NA 201 NA NA 1
7 202 2 NA 201 NA NA 0
8 203 2 201 NA NA 0
9 301 3 NA NA NA 0
10302 3钠钠钠钠0
11 401 4不适用不适用不适用0
由(v2.0.0)于2021-06-09创建
如果您想安全地排除hh\u id
您可以使用
df %>% group_by(personid) %>%
mutate(res = sum(cur_group() %in% cur_data()[-1]))
一种在base中解决此问题的方法,使用=
进行比较并测试行和是否为<0
:
+(rowSums(df[[1]] == df[,3:8], na.rm=TRUE) > 0)
# [1] 1 0 0 0 0 1 0 0 0 0 0
或者将any
与apply
一起使用
+apply(df[[1]] == df[,3:8], 1, any, na.rm = TRUE)
# [1] 1 0 0 0 0 1 0 0 0 0 0
或相同,但使用管道:
(df[[1]] == df[,3:8]) |> rowSums(na.rm=TRUE) |> (`>`)(0) |> as.integer()
(df[[1]] == df[,3:8]) |> apply(1, any, na.rm=TRUE) |> as.integer()
一种在base中解决此问题的方法,使用=
进行比较并测试行和是否为<0
:
+(rowSums(df[[1]] == df[,3:8], na.rm=TRUE) > 0)
# [1] 1 0 0 0 0 1 0 0 0 0 0
或者将any
与apply