2

My head is exploding with this. I can't seem to create a working solution.

I have a file in this format:

99895|35378|0.01
99895|813|-0.97
99895|771|0.29
442|833|-1.06
442|485|-0.61
442|367|-0.14
442|478|0.77
442|947|-0.07
7977|987|0.76
7977|819|0.37
7977|819|0.36
7977|653|1.16
7977|1653|1.15

I want to calculate average values from third column for each id from the first column.

This seems so easy but I can't get this to work. How do you get averages for any said id from first column?

EDIT:

Some sample code I've written before:

$file = file_get_contents("results.txt");


$file = explode("
", $file);

$howMany = count($file);

for($a = 0;$a<$howMany;$a++)
{

$row = explode("|", $file[$a]);
$id = $row[0];



$howManyAlready = count($bigTable[$id]);

$bigTable[$id][$howManyAlready] = $row[2];

}

I've added the code. So far it gets the results into an array ( with offset corresponding to its id ) But I am having trouble with how to get those results and calculate average for each id and then present it on the screen.

5
  • 1
    Please provide the code you wrote already, and solutions you are working on. And tell us what is wrong with your current code. Commented Dec 19, 2013 at 11:48
  • Are you values already in an array, or in a separate file you need to read ? Commented Dec 19, 2013 at 11:49
  • I've deleted it all as it was driving me mad. I was sitting 2 hours at this trivial problem. Commented Dec 19, 2013 at 11:49
  • The values are in a .txt file separated by new lines. Commented Dec 19, 2013 at 11:50
  • @user3010273 Stackoverflow is about the code. Write the algorithm, then write some code, and we will help you if it doesn't work. Here are some functions that might help your : fgetcsv to read your file, array_sum and count to calculate the average for each id. Commented Dec 19, 2013 at 11:52

7 Answers 7

5

Something like this should definitely work..

<?php
$arr=array();
$arrv=array_filter(file('myfile.txt'),'strlen');
foreach($arrv as $v)
{
    array_push($arr,@array_pop(explode('|',$v)));
}
echo $avg = array_sum($arr)/count($arr);
Sign up to request clarification or add additional context in comments.

Comments

1

You can try doing this :

$file = file_get_contents("results.txt");
$file = explode("
", $file);

$valuesPerID = Array();

foreach($file as $row)
{

    $row_array = explode("|", $row);

    $id = $row_array[0];

    if(!array_key_exists($id, $valuesPerID))
    {
        $valuesPerID[$id] = Array();
    }

    $valuesPerID[$id][] = $row_array[2];

}

Now in the $valuesPerID array, you'll have all your ID as keys, and for each ID, all the values associated with the said ID. They you can easily calculate the average of these values !

1 Comment

You should check the file function, that reads an entire file into an array, and takes care of the different possible line endings.
1

You can use array mapping to assign value and id. For example (assume that you have handled the text):

<?php
    $data = array("99895|35378|0.01",
        "99895|813|-0.97",
        "99895|771|0.29",
        "442|833|-1.06",
        "442|485|-0.61",
        "442|367|-0.14",
        "442|478|0.77",
        "442|947|-0.07",
        "7977|987|0.76",
        "7977|819|0.37",
        "7977|819|0.36",
        "7977|653|1.16",
        "7977|1653|1.15");

    $bucket = array();
    $count = array();
    foreach($data as $line) {
        list($id, $what_s_this, $number) = explode("|", $line);
        $count[$id]++;
        $bucket[$id]+= (float)$number;
    }

    foreach($bucket as $id => $sum) {
        echo "id:". $id. ", average". $sum / $count[$id]. "\n";
    }

1 Comment

Just tested, undefined offsets everywhere.
1

This should put you on the right track.

<?php
$values = array();

foreach (file('file.txt') as $line) {
    list($id, $thingymabob, $value) = explode('|', $line);

    if ( ! array_key_exists($id, $values)) {
        $values[ $id ] = array();
    }

    array_push($values[ $id ], $value);
}

foreach ($values as $id => $value) {
    printf(
        "%d has an average of %f\n",
        $id,
        array_sum($value) / count($value)
    );
}

Comments

1

Here some something I've just written.

In my example it takes it from a string.

<?php
$test1 = "";
$test2 = "";
$count1 = 0;
$count2 = 0;
$string = "99895|35378|0.01
99895|813|-0.97
99895|771|0.29
442|833|-1.06
442|485|-0.61
442|367|-0.14
442|478|0.77
442|947|-0.07
7977|987|0.76
7977|819|0.37
7977|819|0.36
7977|653|1.16
7977|1653|1.15";

$d = explode("\n", $string);
foreach ($d as $k => $v)
{
    $d2 = explode("|", $v);

    if ($d2[0] == '99895'){
        $count1++;
        $test1 += $d2[2];
    }
    if ($d2[0] == '442'){
        $count2++;
        $test2 += $d2[2];
    }
}

$result1 = $test1 / $count1;
$result2 = $test2 / $count2;

echo $result1. " <br> ". $result2;

I don't know how well this will work as I don't know if the values are set or not.

Comments

1

If You try below code

<?php
$file_content = array();
$handle = fopen("test.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
        $line_ex = explode("|",$line);
        array_push($file_content,$line_ex);
    }
} else {
    // error opening the file.

}

echo "<pre>";
    print_r($file_content);
    echo "<pre>";
?>

then You will get below output

Array
(
[0] => Array
    (
        [0] => 99895
        [1] => 35378
        [2] => 0.01

    )

[1] => Array
    (
        [0] => 99895
        [1] => 813
        [2] => -0.97

    )

[2] => Array
    (
        [0] => 99895
        [1] => 771
        [2] => 0.29

    )

[3] => Array
    (
        [0] => 442
        [1] => 833
        [2] => -1.06

    )

[4] => Array
    (
        [0] => 442
        [1] => 485
        [2] => -0.61

    )

[5] => Array
    (
        [0] => 442
        [1] => 367
        [2] => -0.14

    )

[6] => Array
    (
        [0] => 442
        [1] => 478
        [2] => 0.77

    )

[7] => Array
    (
        [0] => 442
        [1] => 947
        [2] => -0.07

    )

[8] => Array
    (
        [0] => 7977
        [1] => 987
        [2] => 0.76

    )

[9] => Array
    (
        [0] => 7977
        [1] => 819
        [2] => 0.37

    )

[10] => Array
    (
        [0] => 7977
        [1] => 819
        [2] => 0.36

    )

[11] => Array
    (
        [0] => 7977
        [1] => 653
        [2] => 1.16

    )

[12] => Array
    (
        [0] => 7977
        [1] => 1653
        [2] => 1.15
    )

)

For determining average value from third column of corresponding first column - I am researching on it. When I will be done I'll put it here.

Comments

1

Try this:

$filename = 'results.txt';
$result = $counter = $values = array();

$file = fopen($filename, 'r') or die("Couldn't open $filename");
while ($line = fgets($file)) {
    $content = explode('|', $line);
    if (empty($content[0]) or empty($content[2]))
        continue;

    $values[$content[0]][] = (float) $content[2];
    ++$counter[$content[0]];
}

foreach ($values as $key => $value) {
    $result[$key] = array_sum($value) / $counter[$key];
}
fclose($file);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.