R for循环,如果有则在多个数据帧上

时间:2018-07-31 18:21:18

标签: r if-statement

致意,并预先感谢您提供的所有帮助 我有很多类似于下面的数据框

df1

   name info
1  john    A
2   jim    B
3   tom    B
4 bill     B

dframe

  name other
1  sam   pro
2  dad   mo1
3  mom  Bxxx

frame3

   name otherinfo
1   jus         A
2    do         7
3 r pro         B
4   sir         B
5  real        na
6  pete       yes

OLFrame

   name information
1  ally          x1
2   mom          B9
3 r pro         s3B
4   tom         Bd0
5 kelly          ot
6  jojo         who
7    na          11

我想:

  1. 从数据框“ OLFrame”的“名称”列中获取每个名称,然后查看“ df1”的“名称”列以查看名称是否存在
  2. 如果“ df1”中存在“ df1”的名称(如果不存在“ 0”,则创建名称为“ df1”的列矢量,其中包含“ 1”)
  3. 重复步骤1和2,但使用“ dframe”和“ frame3”
  4. 创建一个名为“ newOLFrame”的新数据框架,其中包括“ OLFrame”和名为“ df1”,“ dframe”和“ frame3”的新列

所需的结果应该像

newOLFrame

   name information df1 dframe frame3
1  ally          x1   0      0      0
2   mom          B9   0      1      0
3 r pro         s3B   0      0      1
4   tom         Bd0   1      0      0
5 kelly          ot   0      0      0
6  jojo         who   0      0      0
7    na          11   0      0      0

我一次只能做一个(下),但是我要浏览一百多个文件

newOLFrame<-OLFrame
newOLFrame[,"pro1"]<-ifelse(newOLFrame$name %in% df12$name, 1, 0)

请帮助。再次感谢

1 个答案:

答案 0 :(得分:3)

通过首先构建数据帧列表来考虑扩展链合并,将其迭代地加入 OLFrame ,然后以Reduce结尾将所有链合并在一起:

df_list <- lapply(c("df1", "dframe", "frame3"), function(nm) {      
  df <- get(nm)
  df[[nm]] <- 1

  df <- merge(OLFrame, df[c("name", nm)], by="name", all.x=TRUE) 
  df[[nm]] = ifelse(is.na(df[[nm]]), 0, 1)

  return(df)
})

# MERGE ALL DFs
final_df <- Reduce(function(x, y) merge(x, y, by=c("name", "information")), df_list)
final_df
#    name information df1 dframe frame3
# 1  ally          x1   0      0      0
# 2  jojo         who   0      0      0
# 3 kelly          ot   0      0      0
# 4   mom          B9   0      1      0
# 5    na          11   0      0      0
# 6 r pro         s3B   0      0      1
# 7   tom         Bd0   1      0      0

或者,考虑do.call,因为Reduce可能会影响大型列表的性能问题,在大型列表中,您需要对数据帧进行排序,然后仅将所需的列子集化,最后在列中绑定所有数据帧项:

df_list <- lapply(c("df1", "dframe", "frame3"), function(nm) {

  df <- get(nm)
  df[[nm]] <- 1

  df <- merge(OLFrame, df[c("name", nm)], by="name", all.x=TRUE, sort=FALSE) 
  df[[nm]] = ifelse(is.na(df[[nm]]), 0, 1)

  df <- with(df, df[order(name, information),])        # ORDER DATA FRAME
  small_df <- setNames(as.data.frame(df[[nm]]), nm)    # SUBSET ONE COLUMN

  return(small_df)
})

# ORDER DATA FRAME
OLFrame <- with(OLFrame, OLFrame[order(name, information),])

final_df <- do.call(cbind, c(OLFrame, df_list))
final_df

#    name information df1 dframe frame3
# 1  ally          x1   0      0      0
# 2  jojo         who   0      0      0
# 3 kelly          ot   0      0      0
# 4   mom          B9   0      1      0
# 5    na          11   0      0      0
# 6 r pro         s3B   0      0      1
# 7   tom         Bd0   1      0      0