使用data.table中某些列的值来确定将使用哪些剩余列

时间:2016-02-29 06:52:59

标签: r data.table

这是我的数据集,

library(data.table)
df <- data.table(
  id = 1:8, 
  start = c(1, 2, 2, 1, 3, 3, 1, 2), 
  end = c(1, 3, 3, 3, 3, 3, 2, 2), 
  t1 = c(0, 1, 1, 1, 1, 0, 1, 0), 
  t2 = c(0, 0, 1, 1, 1, 1, 0, 1), 
  t3 = c(0, 1, 1, 1, 0, 1, 0, 1)
)
df

> tmp
   id start end t1 t2 t3
1:  1     1   1  0  0  0
2:  2     2   3  1  0  1
3:  3     2   3  1  1  1
4:  4     1   3  1  1  1
5:  5     3   3  1  1  0
6:  6     3   3  0  1  1
7:  7     1   2  1  0  0
8:  8     2   2  0  1  1

对于每一行,我想创建一个列x并将其分配给TRUE,如果列paste0(t, start)paste0(t, end)全部为1,否则FALSE

所以期望的输出应该是

   id start end t1 t2 t3     x
1:  1     1   1  0  0  0 FALSE # t1 is 0
2:  2     2   3  1  0  1 FALSE # t2 is 0
3:  3     2   3  1  1  1  TRUE # t2 to t3 are all 1
4:  4     1   3  1  1  1  TRUE # t1 to t3 are all 1
5:  5     3   3  1  1  0 FALSE # t3 is 0
6:  6     3   3  0  1  1  TRUE # t3 is 1
7:  7     1   2  1  0  0 FALSE # t2 is 0
8:  8     2   2  0  1  1  TRUE # t2 is 1

我可以在不使用每行for循环的情况下实现我的目标吗?谢谢!

2 个答案:

答案 0 :(得分:2)

我们可以melt从'wide'到'long'的数据集,然后按'id'分组,我们得到'value'的元素,它们对应于'start'和'end'之间的序列,并检查all值是否不等于0.输出将是一个逻辑向量,我们可以将其作为'x'分配给原始数据集。

df[, x:=melt(.SD, measure = 4:6)[, 
       all(value[start[1L]:end[1L]]!=0), id]$V1]
df
#  id start end t1 t2 t3     x
#1:  1     1   1  0  0  0 FALSE
#2:  2     2   3  1  0  1 FALSE
#3:  3     2   3  1  1  1  TRUE
#4:  4     1   3  1  1  1  TRUE
#5:  5     3   3  1  1  0 FALSE
#6:  6     3   3  0  1  1  TRUE
#7:  7     1   2  1  0  0 FALSE
#8:  8     2   2  0  1  1  TRUE

或者我们按行序列分组

df[, x:={nm1 <- names(df)[(start:end)+3L]
   list( Reduce(`+`, .SD[, nm1, with=FALSE])==length(nm1)) }
          , 1:nrow(df)]
df
# id start end t1 t2 t3     x
#1:  1     1   1  0  0  0 FALSE
#2:  2     2   3  1  0  1 FALSE
#3:  3     2   3  1  1  1  TRUE
#4:  4     1   3  1  1  1  TRUE
#5:  5     3   3  1  1  0 FALSE
#6:  6     3   3  0  1  1  TRUE
#7:  7     1   2  1  0  0 FALSE
#8:  8     2   2  0  1  1  TRUE

答案 1 :(得分:2)

我们可以编写一个函数来为每个数据帧行执行此操作,然后逐行应用它

df$x <- apply(df,1,function(x) {all(x[ (x[2]+3) : (x[3]+3) ]==1)})

内联函数接受来自数据框的一行数据,然后从该行获取相应的列(x[2]是起始值,因此x[2]+3给出了x[3]+3的起始列和类似apply 1}})并根据值1检查这些值,如果它们都是1则返回。

df函数将此内联函数应用于数据帧的每一行(第二个参数的值为1表示按行工作)并返回每行的结果。然后我们将其分配给数据帧。

运行此功能后, id start end t1 t2 t3 x 1: 1 1 1 0 0 0 FALSE 2: 2 2 3 1 0 1 FALSE 3: 3 2 3 1 1 1 TRUE 4: 4 1 3 1 1 1 TRUE 5: 5 3 3 1 1 0 FALSE 6: 6 3 3 0 1 1 TRUE 7: 7 1 2 1 0 0 FALSE 8: 8 2 2 0 1 1 TRUE 看起来像

$args = array(
    'posts_per_page' => 4,
    'offset' => 0,
    'orderby' => 'post_date',
    'order' => 'DESC',
    'post_type' => 'post',
    'post_status' => 'publish',
    'suppress_filters' => true);

$recent_postss = wp_get_recent_posts($args, ARRAY_A);
?> 

foreach ($recent_postss as $posts) { } 

根据需要。