【问题标题】:Loop a if statment through rows通过行循环 if 语句
【发布时间】:2017-09-12 07:06:06
【问题描述】:

我对 R 比较陌生,所以我问了一个基本问题。

我有两个数据框

数据框 1 包含匹配对:

Factor1 Factor2
  A       D
  B       E
  C       F

数据框2包含不同样本中不同因素的水平:

  Sample1 Sample2
A   10      0
B   10      0
C   0       0
D   0       10
E   0       10
F   0       0

我正在尝试遍历第一个数据帧。对于数据框 1 中的每一行,如果样本 1 中因子 1 的水平大于 5,样本 2 中因子 2 的水平大于 5,则在数据框 1 的第三列中添加 TRUE。否则添加 FALSE。我希望我的问题足够清楚。谢谢

Factor1 Factor2 if_match
  A       D       TRUE
  B       E       TRUE
  C       F       FALSE

【问题讨论】:

  • 到目前为止你有没有尝试过?
  • data.frame 2 中的 A、B、C... 是列还是行名称?

标签: r


【解决方案1】:

假设两个数据集中的列数相同,使用match通过比较'df2'的行名与'df1'的每一列的行名得到行的索引,然后得到对应的第二个数据集的列值,检查它是否大于或等于5和Reduce它到单个逻辑vector

df2$if_match <- Reduce(`|`, Map(function(x, y) y[match(row.names(df2), 
                    x, nomatch = 0)] >=5 , df1, df2))
df2$if_match
#[1]  TRUE  TRUE FALSE

【讨论】:

    【解决方案2】:

    假设 data.frame 2 的 row.names 等于 data.frame 1 中的因子,您可以使用 row.names 子集:

    DF1$if_match <- DF2[as.character(DF1$Factor1),'Sample1'] > 5 &
                    DF2[as.character(DF1$Factor2),'Sample2'] > 5
    
    > DF1
      Factor1 Factor2 if_match
    1       A       D     TRUE
    2       B       E     TRUE
    3       C       F    FALSE
    

    编辑:
    请注意,由 row.names 设置的 data.frame 子集使用部分匹配,因此例如 DF['A',] 将同时找到 'A''A123'(如果存在于 row.names(DF) 中)。
    因此,如果您的数据可能有部分匹配的因素,我建议您改用以下代码(如 data.frame subset documentation 中所建议的那样):

    DF1$if_match <- DF2$Sample1[ match(as.character(DF1$Factor1),row.names(DF2)) ] > 5 &
                    DF2$Sample2[ match(as.character(DF1$Factor2),row.names(DF2)) ] > 5
    

    重现您的示例数据的代码:

    DF1 <- read.csv(text=
    'Factor1,Factor2
    A,D
    B,E
    C,F')
    
    DF2 <- read.csv(text=
    'Sample1,Sample2
    A,10,0
    B,10,0
    C,0,0
    D,0,10
    E,0,10
    F,0,0')
    

    【讨论】:

      猜你喜欢
      • 2013-12-29
      • 2021-02-15
      • 1970-01-01
      • 2018-04-28
      • 2021-03-28
      • 1970-01-01
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多