3

与往常一样,总是感谢帮助/评论的想法,并为我的编程天真表示歉意。

我正在尝试创建一个广泛适用的函数,可用于未来涉及块随机化的研究。patientDataCollection 的每个成员都有一个布尔属性,命名为interventionArm、givenDrugX 或类似的东西。该功能旨在(伪)随机分配给研究组,具体取决于块大小 - 也就是说,如果块大小为 8,则将 4 分配给治疗,将 4 分配给控制(无治疗)。

到目前为止的代码:

 public static bool nextAllocation<T>(int blockSize, IEnumerable<T> patientDataCollection, string allocationPropertyName)
 {
    int remainingAllocations = blockSize - patientDataCollection.Count();
    if (remainingAllocations <= 0) throw new Exception("All alocations within block accounted for");
    var p = typeof(T).GetProperty(allocationPropertyName);

    int remainingInterventions = blockSize/2 - patientDataCollection.Count(c => c.p);
    double Pintervention = (double)remainingInterventions / (double)remainingAllocations;
    double rdm = new Random().NextDouble();
    return (rdm <= Pintervention);
 }

这当然是有缺陷的逻辑,因为变量 p 与 linq 语句 PatientDataCollection.Count(c => cp) 中引用的 cp 无关。显然,这个语句只是简单地计算所有具有真值的元素。

ASP 为 4.0。谁能看到如何实现这一目标

4

3 回答 3

2

Func<T, bool>您可以将用于计数的方法传递给您的方法。

public static bool nextAllocation<T>(int blockSize, IEnumerable<T> patientDataCollection, Func<T,bool> predicate) 
{ 
    int remainingAllocations = blockSize - patientDataCollection.Count(); 
    if (remainingAllocations == 0) throw new Exception("All alocations within block accounted for"); 
    int remainingInterventions = blockSize/2 - patientDataCollection.Count(predicate); 
    double Pintervention = remainingInterventions / remainingAllocations; 
    double rdm = new Random().NextDouble(); 
    return (rdm <= Pintervention); 
}

使用示例如下:

var result = nextAllocation(10, collection, c=>c.interventionArm);
于 2012-06-29T08:16:15.307 回答
1

您可以使用反射来获取属性的值:

int remainingInterventions = blockSize/2 - 
    patientDataCollection.Count(c => (bool)p.GetValue(c,null));

也添加错误检查。

于 2012-06-29T02:08:27.817 回答
0

尝试使用表达式

public static class ExpressionCreator
{
    public static Func<T, TProperty> CreatePropertyAccessExpression<T, TProperty>(string propertyName)
    {
        var tType = typeof (T);
        var property = tType.GetProperty(propertyName);
        var parameterExpression = Expression.Parameter(tType);
        var memberAccessExpression = Expression.MakeMemberAccess(parameterExpression, property);
        var lambda = Expression.Lambda<Func<T, TProperty>>(memberAccessExpression, parameterExpression);
        return lambda.Compile();
    }
}

示例用法:

    public class A
    {
        public bool Thing1 { get; set; }
        public bool Thing2 { get; set; }
    }

    static void Main(string[] args)
    {
        var @as = new A[10];
        for(var i = 0; i < @as.Length; i+=2)
        {
            @as[i] = new A {Thing1 = true};
            @as[i + 1] = new A {Thing2 = i%4 == 0};
        }

        var thing1Expression = ExpressionCreator.CreatePropertyAccessExpression<A, bool>("Thing1");
        var thing2Expression = ExpressionCreator.CreatePropertyAccessExpression<A, bool>("Thing2");
        Console.WriteLine(@as.Count(thing1Expression));
        Console.WriteLine(@as.Count(thing2Expression));
        Console.ReadLine();
    }
于 2012-06-29T05:58:03.220 回答