[英]Mapping columns/rows from one dataframe to another based on row number
I have two dataframes: 我有两个数据帧:
df1<-structure(list(Name = c("sub7", "sub7", "sub7", "sub7", "sub7",
"sub7", "sub7", "sub7", "sub7", "sub7"), StimulusName = c("Alpha1",
"Alpha1", "Alpha1", "Alpha1", "Alpha1", "Alpha1", "Alpha1", "Alpha1",
"Alpha1", "Alpha1"), PupilLeft = c(10.046, 10.05, 10.062, 10.072,
10.072, 10.056, 10.056, 10.056, 10.066, 10.066)), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"))
df2<-structure(list(Name = c("sub7", "sub7"), StimulusName = c("Alpha1",
"Alpha1"), Row_Num = c(1, 3), Label = c("Onset", "Offset")), row.names = c(NA,
-2L), vars = "Name", drop = TRUE, indices = list(0:1), group_sizes = 2L, biggest_group_size = 2L, labels = structure(list(
Name = "Guilty Subject 07"), row.names = c(NA, -1L), class = "data.frame", vars = "Name", drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
I'd like to take the values from the columns Row_Num
and Label
in df2
and map them to rows in df1
corresponding to the numbers in Row_Num
. 我想从
df2
Row_Num
和Label
列中Row_Num
值,并将它们映射到df1
与Row_Num
的数字对应的行。
I would like to achieve this without using loops. 我想在不使用循环的情况下实现此目的。 Perhaps just using the
Row_Num
values as an index? 也许只是使用
Row_Num
值作为索引?
The final dataframe in this instance would look like: 此实例中的最终数据框如下所示:
Name StimulusName PupilLeft Row_Num Label
1 sub7 Alpha1 10.0 1 Onset
2 sub7 Alpha1 10.0 NA NA
3 sub7 Alpha1 10.1 3 Offset
4 sub7 Alpha1 10.1 NA NA
5 sub7 Alpha1 10.1 NA NA
6 sub7 Alpha1 10.1 NA NA
7 sub7 Alpha1 10.1 NA NA
8 sub7 Alpha1 10.1 NA NA
9 sub7 Alpha1 10.1 NA NA
10 sub7 Alpha1 10.1 NA NA
Another option is to create Row_Num
in df1
before you merge. 另一个选项是在合并之前在
df1
创建Row_Num
。
df_out <- merge(
transform(df1, Row_Num = seq_len(nrow(df1))),
df2,
by = c("Name", "StimulusName", "Row_Num"),
all.x = TRUE)
df_out$Row_Num <- ifelse(df_out$Row_Num %in% df2$Row_Num, df_out$Row_Num, NA)
df_out
# Name StimulusName Row_Num PupilLeft Label
#1 sub7 Alpha1 1 10.046 Onset
#2 sub7 Alpha1 NA 10.050 <NA>
#3 sub7 Alpha1 3 10.062 Offset
#4 sub7 Alpha1 NA 10.072 <NA>
#5 sub7 Alpha1 NA 10.072 <NA>
#6 sub7 Alpha1 NA 10.056 <NA>
#7 sub7 Alpha1 NA 10.056 <NA>
#8 sub7 Alpha1 NA 10.056 <NA>
#9 sub7 Alpha1 NA 10.066 <NA>
#10 sub7 Alpha1 NA 10.066 <NA>
Using tidyverse
使用
tidyverse
library(tidyverse)
df1 %>%
mutate(Row_Num = row_number()) %>%
left_join(df2) %>%
mutate(Row_Num = replace(Row_Num, !Row_Num %in% c(1, 3), NA))
# A tibble: 10 x 5
# Name StimulusName PupilLeft Row_Num Label
# <chr> <chr> <dbl> <dbl> <chr>
# 1 sub7 Alpha1 10.0 1 Onset
# 2 sub7 Alpha1 10.0 NA <NA>
# 3 sub7 Alpha1 10.1 3 Offset
# 4 sub7 Alpha1 10.1 NA <NA>
# 5 sub7 Alpha1 10.1 NA <NA>
# 6 sub7 Alpha1 10.1 NA <NA>
# 7 sub7 Alpha1 10.1 NA <NA>
# 8 sub7 Alpha1 10.1 NA <NA>
# 9 sub7 Alpha1 10.1 NA <NA>
#10 sub7 Alpha1 10.1 NA <NA>
If it is to join by row names 如果是按行名加入
rownames_to_column(df1, "Row_Num") %>%
mutate(Row_Num = as.numeric(Row_Num)) %>%
left_join(., df2 %>%
ungroup %>%
select(Row_Num, Label), by = "Row_Num") %>%
mutate(Row_Num = replace(Row_Num, !Row_Num %in% c(1, 3), NA))
Or using match
from base R
或使用
base R
match
i1 <- match(row.names(df1), df2$Row_Num)
df1[names(df2)[3:4]] <- lapply(df2[3:4], `[`, i1)
df1
# A tibble: 10 x 5
# Name StimulusName PupilLeft Row_Num Label
# <chr> <chr> <dbl> <dbl> <chr>
# 1 sub7 Alpha1 10.0 1 Onset
# 2 sub7 Alpha1 10.0 NA <NA>
# 3 sub7 Alpha1 10.1 3 Offset
# 4 sub7 Alpha1 10.1 NA <NA>
# 5 sub7 Alpha1 10.1 NA <NA>
# 6 sub7 Alpha1 10.1 NA <NA>
# 7 sub7 Alpha1 10.1 NA <NA>
# 8 sub7 Alpha1 10.1 NA <NA>
# 9 sub7 Alpha1 10.1 NA <NA>
#10 sub7 Alpha1 10.1 NA <NA>
If we are only joining by Row_Num
then we could do: 如果我们只是通过
Row_Num
加入,那么我们可以这样做:
rownames(df2) <- df2$Row_Num
merge(df1, df2, by=0, all.x=TRUE)
Row.names Name.x StimulusName.x PupilLeft Name.y StimulusName.y Row_Num Label
1 1 sub7 Alpha1 10.046 sub7 Alpha1 1 Onset
2 10 sub7 Alpha1 10.066 <NA> <NA> NA <NA>
3 2 sub7 Alpha1 10.050 <NA> <NA> NA <NA>
4 3 sub7 Alpha1 10.062 sub7 Alpha1 3 Offset
5 4 sub7 Alpha1 10.072 <NA> <NA> NA <NA>
6 5 sub7 Alpha1 10.072 <NA> <NA> NA <NA>
7 6 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
8 7 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
9 8 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
10 9 sub7 Alpha1 10.066 <NA> <NA> NA <NA>
Alternatively, you might want to use: 或者,您可能想要使用:
merge(df1, df2, by="row.names", all.x=TRUE)
To make the by argument a little less cryptic. 使论证变得不那么神秘。
How about merge
? merge
怎么样?
df2 <- data.frame(df2, stringsAsFactors = F)
df3 <- merge(df1,df2)
> df3
Name StimulusName PupilLeft Row_Num Label
1 sub7 Alpha1 10.046 1 Onset
2 sub7 Alpha1 10.046 3 Offset
3 sub7 Alpha1 10.050 1 Onset
4 sub7 Alpha1 10.050 3 Offset
5 sub7 Alpha1 10.062 1 Onset
6 sub7 Alpha1 10.062 3 Offset
7 sub7 Alpha1 10.072 1 Onset
8 sub7 Alpha1 10.072 3 Offset
9 sub7 Alpha1 10.072 1 Onset
10 sub7 Alpha1 10.072 3 Offset
11 sub7 Alpha1 10.056 1 Onset
12 sub7 Alpha1 10.056 3 Offset
13 sub7 Alpha1 10.056 1 Onset
14 sub7 Alpha1 10.056 3 Offset
15 sub7 Alpha1 10.056 1 Onset
16 sub7 Alpha1 10.056 3 Offset
17 sub7 Alpha1 10.066 1 Onset
18 sub7 Alpha1 10.066 3 Offset
19 sub7 Alpha1 10.066 1 Onset
20 sub7 Alpha1 10.066 3 Offset
EDIT: using your proposed method with rownames as index: 编辑:使用您提出的方法将rownames作为索引:
df1$id <- 1:nrow(df1)
df2$id <- 1:nrow(df2)
df4 <- merge(df1,df2, by="id", all.x=T)
> df4
id Name.x StimulusName.x PupilLeft Name.y StimulusName.y Row_Num Label
1 1 sub7 Alpha1 10.046 sub7 Alpha1 1 Onset
2 2 sub7 Alpha1 10.050 sub7 Alpha1 3 Offset
3 3 sub7 Alpha1 10.062 <NA> <NA> NA <NA>
4 4 sub7 Alpha1 10.072 <NA> <NA> NA <NA>
5 5 sub7 Alpha1 10.072 <NA> <NA> NA <NA>
6 6 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
7 7 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
8 8 sub7 Alpha1 10.056 <NA> <NA> NA <NA>
9 9 sub7 Alpha1 10.066 <NA> <NA> NA <NA>
10 10 sub7 Alpha1 10.066 <NA> <NA> NA <NA>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.